IEEE Floating-Point Demos¶

In [2]:
import numpy as np

Overflow¶

In [3]:
2.**1023
Out[3]:
8.98846567431158e+307
In [4]:
2.**1024
---------------------------------------------------------------------------
OverflowError                             Traceback (most recent call last)
Cell In[4], line 1
----> 1 2.**1024

OverflowError: (34, 'Result too large')
In [6]:
-np.float64(2.)**1024
/var/folders/97/ppgk101x3214hn7bzlb85jk00000gn/T/ipykernel_41109/3987387186.py:1: RuntimeWarning: overflow encountered in scalar power
  -np.float64(2.)**1024
Out[6]:
np.float64(-inf)

Underflow¶

In [7]:
2.**(-1022)
Out[7]:
2.2250738585072014e-308
In [8]:
2.**(-1022) * 2.**(-1)
Out[8]:
1.1125369292536007e-308
In [14]:
2.**(-1022) * 2.**(-52)
Out[14]:
5e-324

Exceptions¶

In [16]:
np.double(1.)/(-0.)
/var/folders/97/ppgk101x3214hn7bzlb85jk00000gn/T/ipykernel_41109/2823736679.py:1: RuntimeWarning: divide by zero encountered in scalar divide
  np.double(1.)/(-0.)
Out[16]:
np.float64(-inf)
In [18]:
-2. / np.inf
Out[18]:
-0.0
In [21]:
(np.inf - 2.) - 8
Out[21]:
inf
In [22]:
np.double(0.) / 0.
/var/folders/97/ppgk101x3214hn7bzlb85jk00000gn/T/ipykernel_41109/2462110309.py:1: RuntimeWarning: invalid value encountered in scalar divide
  np.double(0.) / 0.
Out[22]:
np.float64(nan)

Machine Epsilon¶

In [23]:
# too small
eps = 2**(-53)
print(f'ε = 1.0 * 2**(-53)')
print( (1.+eps) - 1. )
ε = 1.0 * 2**(-53)
0.0
In [24]:
# Let's try this larger one
eps = 2**(-52)
print(f'ε = 1.0 * 2**(-52)')
print( (1.+eps) - 1. )
ε = 1.0 * 2**(-52)
2.220446049250313e-16
In [25]:
# OK, something between those two
bs = '11'
print(f'ε = {bs[0]}.{bs[1:]} * 2^(-53)')
eps = int(bs, 2) * 2**(-1) * 2**(-53)
print(eps)
print( (1.+eps) - 1. )
ε = 1.1 * 2^(-53)
1.6653345369377348e-16
2.220446049250313e-16
In [26]:
# Same idea, but smaller
bs = '1'
for k in range(50):
    bs += '0'
bs += '1'
print(f'eps = {bs[0]}.{bs[1:]} * 2^(-53)')
eps = int(bs, 2) * 2**(-len(bs)) * 2**(-52)
print(eps)
print( (1.+eps) - 1. )
eps = 1.000000000000000000000000000000000000000000000000001 * 2^(-53)
1.110223024625157e-16
2.220446049250313e-16
In [27]:
np.finfo(np.double).eps
Out[27]:
np.float64(2.220446049250313e-16)
In [28]:
np.finfo(np.single).eps
Out[28]:
np.float32(1.1920929e-07)
In [29]:
np.pi
Out[29]:
3.141592653589793
In [30]:
np.single(np.pi)
Out[30]:
np.float32(3.1415927)
In [31]:
# How many base-10 digits cover the range of 52 base-2 digits?
np.log10(2**52)
Out[31]:
np.float64(15.653559774527022)
In [32]:
# How many base-10 digits cover the range of 52 base-2 digits?
np.log10(2**23)
Out[32]:
np.float64(6.923689900271567)
In [33]:
np.double(0.)**0.
Out[33]:
np.float64(1.0)
In [37]:
np.log(0. * np.inf)
Out[37]:
np.float64(nan)
In [ ]: