Skip to content

Instantly share code, notes, and snippets.

@kentquirk
Created May 27, 2014 13:40
Show Gist options
  • Save kentquirk/3644a03c6a037b7cf0ba to your computer and use it in GitHub Desktop.
Save kentquirk/3644a03c6a037b7cf0ba to your computer and use it in GitHub Desktop.
Shows how storing data in ints is a problem but in floats works just fine
# This is a small program that tests conversion to and from different formats
# and makes sure that numbers that undergo conversion don't lose precision.
import math
# truncates a number to the given number of digits after the decimal
def truncate(x, digits):
p = math.pow(10, digits)
return int(x * p)/p
def round(x, digits):
p = math.pow(10, digits)
return int(x * p + 0.5)/p
# prove that they work, more or less
assert(truncate(math.pi, 0) == 3)
assert(truncate(math.pi, 2) == 3.14)
assert(truncate(math.pi, 4) == 3.1415)
assert(truncate(1.5, 0) == 1)
assert(round(math.pi, 0) == 3)
assert(round(math.pi, 2) == 3.14)
assert(round(math.pi, 4) == 3.1416)
assert(round(1.5, 0) == 2)
# now let's deal with conversions
conversion = 18.01559
def cvt_Euro_US(bg):
return bg * conversion
def cvt_US_Euro(bg):
return bg / conversion
US_samples = [ 40, 67, 95, 120, 240, 450 ]
Euro_samples = [ 2.2, 3.7, 5.3, 6.6, 13.3, 24.9 ]
def store_US_as_US_int(x):
storedValue = int(x)
fetchedValue = storedValue
return fetchedValue
def store_Euro_as_US_int(x):
storedValue = int(cvt_Euro_US(x))
fetchedValue = truncate(storedValue, 1)
return fetchedValue
def store_US_as_Euro_float(x):
storedValue = cvt_US_Euro(x)
fetchedValue = round(x, 0)
return fetchedValue
def store_Euro_as_Euro_float(x):
storedValue = x
fetchedValue = round(x, 1)
return fetchedValue
def store_US_as_US_float(x):
storedValue = float(x)
fetchedValue = round(x, 0)
return fetchedValue
def store_Euro_as_US_float(x):
storedValue = cvt_Euro_US(x)
fetchedValue = round(x, 1)
return fetchedValue
def test(f, values):
print "*** %s ***" % f.__name__
failed = False
for v in values:
try:
assert(v == f(v))
except AssertionError:
print " Failed on %s" % v
failed = True
if not failed:
print " All good."
print
# Test our sample values
print "If we store things as integers, it works fine for US values"
test(store_US_as_US_int, US_samples)
print "But it fails for euro values"
test(store_Euro_as_US_int, Euro_samples) # this is the only test that fails
print "But if we store as floating point Euro values, it all works fine"
test(store_US_as_Euro_float, US_samples)
test(store_Euro_as_Euro_float, Euro_samples)
print "We can even store as US, even if we use floating point."
test(store_US_as_Euro_float, US_samples)
test(store_Euro_as_Euro_float, Euro_samples)
print "And to prove it, let's test all US values from 0 to 2000"
test(store_US_as_Euro_float, range(2000))
print "And again with all Euro values from 0 to 50"
test(store_Euro_as_Euro_float, [round(x/10.0, 1) for x in range(500)])
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment