-2

i have the following code:

a = 0.0
b = 0.0
c = 1.0
while a < 300:
    a = a + 1
    b = b + 1
    c = c * b
    d = (3**a)
    e = (a+1)*c
    f = d / e
    print a, f

The moment f becomes less than 1, I get "0" displayed.. why?

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343

1 Answers1

1

The moment f becomes less than 1, I get "0" displayed

That's not what happens. The first time f is less than 1, 4.0 0.675 is printed. That's not 0:

1.0 1.5
2.0 1.5
3.0 1.125
4.0 0.675
5.0 0.3375

The value of f then quickly becomes very very small, to the point Python starts using scientific notation negative exponents:

6.0 0.144642857143
7.0 0.0542410714286
8.0 0.0180803571429
9.0 0.00542410714286
10.0 0.00147930194805
11.0 0.000369825487013
12.0 8.53443431568e-05
13.0 1.82880735336e-05
14.0 3.65761470672e-06
15.0 6.8580275751e-07

Note the -05, -06, etc. The value of f has become so small that it is more efficient to shift the decimal point. If you were to format those values using fixed-point notation, they'd use more zeros:

>>> format(8.53443431568e-05, '.53f')
'0.00008534434315680000128750276600086976941383909434080'
>>> format(6.8580275751e-07, '.53f')
'0.00000068580275751000002849671038224199648425383202266'

Eventually, f becomes too small for the floating point type; floating point values simply can't go closer to zero beyond this point:

165.0 5.89639287564e-220
166.0 1.05923225311e-221
167.0 1.89148616627e-223
168.0 3.35766775077e-225
169.0 5.92529603077e-227
170.0 0.0

The last value before 0.0 is 5.925 with two hundred and twenty seven zeros before it:

>>> format(5.92529603077e-227, '.250f')
'0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000592529603077000028336751'

That's pretty close to the absolute minimum value a float object can represent; see the min attribute of the sys.float_info named tuple:

>>> import sys
>>> sys.float_info.min
2.2250738585072014e-308

In other words, you reached the limits, and there was no more representable value between 5.92529603077e-227 and 0.0 left.

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343