Repository: pytorch/pytorch

Issue:
print(torch.DoubleTensor(1)) # ZeroDivisionError: float division by zero
on print(torch.DoubleTensor(1)) I got ZeroDivisionError: float division by zero
but torch.DoubleTensor(0)) or torch.DoubleTensor(2)) work just fine.
I work in Jupyter notebook pytorch 0.1.12


Discussion:
Note that `torch.DoubleTensor(1)` returns undefined memory. Could you find the specific content of the tensor that gave this error, by printing `tensor[0]`? I'm not sure if this bug has been fixed in the latest release already.
the error is pretty interesting. I restarted Jupyter notebook.
`# many freaking signatures:
print(torch.FloatTensor(1))
print(torch.IntTensor(1))
print(torch.DoubleTensor(1)) # no error right after initial run.
#print(torch.DoubleTensor(0))
print(torch.DoubleTensor(2))
print(torch.ByteTensor(1))
print(torch.CharTensor(1))
print(torch.ShortTensor(1))
print(torch.LongTensor(1))`

steps to reproduce the error:
1). run, no errors
2) repeat, no error
3) uncomment ..DoubleTensor(0), run, got an error (see below):
4) comment ..DouleTensor(0), run still have this error 

`2.0980e+24
[torch.FloatTensor of size 1]


 7.6169e+08
[torch.IntTensor of size 1]

---------------------------------------------------------------------------
ZeroDivisionError                         Traceback (most recent call last)
<ipython-input-5-3629c250c505> in <module>()
      2 print(torch.FloatTensor(1))
      3 print(torch.IntTensor(1))
----> 4 print(torch.DoubleTensor(1)) # ZeroDivisionError: float division by zero
      5 #print(torch.DoubleTensor(0))
      6 print(torch.DoubleTensor(2))

C:\Users\leo_g\AppData\Local\conda\conda\envs\py35\lib\site-packages\torch\tensor.py in __str__(self)
    126         # characters to replace unicode characters with.
    127         if sys.version_info > (3,):
--> 128             return _tensor_str._str(self)
    129         else:
    130             if hasattr(sys.stdout, 'encoding'):

C:\Users\leo_g\AppData\Local\conda\conda\envs\py35\lib\site-packages\torch\_tensor_str.py in _str(self)
    284         return '[{} with no dimension]\n'.format(torch.typename(self))
    285     elif self.ndimension() == 1:
--> 286         strt = _vector_str(self)
    287     elif self.ndimension() == 2:
    288         strt = _matrix_str(self)

C:\Users\leo_g\AppData\Local\conda\conda\envs\py35\lib\site-packages\torch\_tensor_str.py in _vector_str(self)
    270     if self.numel() < PRINT_OPTS.threshold:
    271         return (strt +
--> 272                 '\n'.join(ident + fmt.format(val / scale) for val in self) +
    273                 '\n')
    274     else:

C:\Users\leo_g\AppData\Local\conda\conda\envs\py35\lib\site-packages\torch\_tensor_str.py in <genexpr>(.0)
    270     if self.numel() < PRINT_OPTS.threshold:
    271         return (strt +
--> 272                 '\n'.join(ident + fmt.format(val / scale) for val in self) +
    273                 '\n')
    274     else:

ZeroDivisionError: float division by zero`
Ok, I got a repro.

Here is the failing case:
```python
print(torch.DoubleTensor([1e-323]))
```
Fails with the error you mentioned. This seems to be an edge case though, as both `1e-322` and `1e-324` works.

The issue is in [this line](https://github.com/pytorch/pytorch/blob/master/torch/_tensor_str.py#L122), where `scale` becomes zero because `exp_max` is a too large negative number. Maybe we should clip `scale` to be positive?

Resolving patch:
diff --git a/torch/_tensor_str.py b/torch/_tensor_str.py
--- a/torch/_tensor_str.py
+++ b/torch/_tensor_str.py
@@ -2,6 +2,10 @@
 import torch
 from functools import reduce
 from ._utils import _range
+from sys import float_info
+
+
+__MIN_LOG_SCALE = math.ceil(math.log(float_info.min * float_info.epsilon, 10))
 
 
 class __PrinterOptions(object):
@@ -119,7 +123,7 @@ def _number_format(tensor, min_sz=-1):
         else:
             if exp_max > prec + 1 or exp_max < 0:
                 sz = max(min_sz, 7)
-                scale = math.pow(10, exp_max - 1)
+                scale = math.pow(10, max(exp_max - 1, __MIN_LOG_SCALE))
             else:
                 if exp_max == 0:
                     sz = 7


Test patch:
diff --git a/test/test_torch.py b/test/test_torch.py
--- a/test/test_torch.py
+++ b/test/test_torch.py
@@ -4049,6 +4049,10 @@ def test_print(self):
         x.__repr__()
         str(x)
 
+        x = torch.DoubleTensor([1e-324, 1e-323, 1e-322, 1e307, 1e308, 1e309])
+        x.__repr__()
+        str(x),
+
     def test_unsqueeze(self):
         x = torch.randn(2, 3, 4)
         y = x.unsqueeze(1)