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()
74.14% of values within 1.0 ULP