(1.1-0.8) == 0.3 sum([0.1]*8) # associativity failure (1.0e-8+1.0)-1.0 == 1.0e-8+(1.0-1.0) # commutativity failure (0.1+0.2+0.3) == (0.3+0.2+0.1) int('0b1101',2) int('0b1110101',2) bin(1742) 0.3 1.1-0.8 from numpy import abs def near(a, b, rtol=1e-5, atol=1e-8): try: return abs(a-b)<(atol+rtol*abs(b)) except TypeError: return False from numpy import arange dx = 0.1 xhi = 2.0 xlo = 1.0 x = arange(xlo, xhi+dx, dx) #same array as above print('x[9] from arange =', repr(x[9])) print(1.9) print('x[9] == 1.9?', (x[9] == 1.9)) #numerical drift is too great print('near(x[9], 1.9)?', near(x[1], 1.1)) print (1.0e-8+1.0)-1.0 print 1.0e-8+(1.0-1.0) x = 5.0/9.0 y = 100*x print y, int(y), round(y) 1.7976931348623157e+308 + 1 1.7976931348623157e+308 + 1e250 1.7976931348623157e+308 + 1e300 # Find the point at which addition of the unit value can no longer be captured accurately by the addition operation. x = 1.0 p = 0 while x != x + 1: x *= 2 p += 1 print "x =", x print "p =", p import sys print sys.float_info float('inf')/float('inf') # actual multiplier on Patriot interceptor hardware dt = 2**-4+2**-5 + 2**-8+2**-9 + 2**-12+2**-13 + 2**-16+2**-17 + 2**-20+2**-21 # "real life" tenth of a second (or in this case, double precision) dT = 0.1 uptime = 100*60*60*10 #ds (deciseconds ... a little odd) assumed_diff = (uptime*dt) real_diff = (uptime*dT) real_diff - assumed_diff # difference in Scud missile position as a result v = 1676 # m/s v*(real_diff-assumed_diff) # m sum([0.1]*8) from math import fsum fsum([0.1]*8) corrected_diff = fsum([dt]*uptime) real_diff - corrected_diff sum([.1, .1, .1, .1, .1, .1, .1, .1, .1, .1]) # fsum will solve issues related to drift in repeated operations. from math import fsum fsum([.1, .1, .1, .1, .1, .1, .1, .1, .1, .1]) # fsum will not solve fundamental precision errors--- print 'fsum([1.1, -0.8]) == 0.3 is', fsum([1.1, -0.8]) == 0.3 #---but will mitigate accumulated error. print 'fsum([.1, .1, .1, .1, .1, .1, .1, .1, .1, .1]) == 1.0 is', fsum([.1, .1, .1, .1, .1, .1, .1, .1, .1, .1]) == 1.0