import pandas as pd from cStringIO import StringIO import random from decimal import Decimal import numpy as np import matplotlib.pyplot as plt def xstrtod(s): return pd.read_csv(StringIO(s), header=None)[0][0] def randnum(): s = '0.' for i in range(20): s += random.choice('0123456789') return s def ulp(s): num = Decimal(s) f = np.float64(s) a = f.view((np.uint8, 8)) if Decimal(f) < num: a[0] += 1 elif Decimal(f) > num: a[0] -= 1 f2 = a.view(np.float64)[0] return abs(f2 - f) y = [] good_vals = 0 for i in range(10000): val = randnum() guess = xstrtod(val) ulp_diff = abs(Decimal(val) - Decimal(guess)) / Decimal(ulp(val)) y.append(float(ulp_diff)) if float(ulp_diff) < 1.0: good_vals += 1 print('{0}% of values within 1.0 ULP'.format(good_vals * 100.0 / 10000)) plt.hist(y, bins=20) plt.show()