float_aligned_quantize_test.py (3150B)
1 #!/usr/bin/env python3 2 from bisect import bisect_left 3 from fractions import Fraction 4 import math 5 import struct 6 import sys 7 import unittest 8 9 from float_aligned_quantize import cases, exact, nearest 10 from float_quantize import BIAS, dyadic, value 11 12 13 class FarAlignmentTests(unittest.TestCase): 14 def test_exhaustive_small_precision_midpoint_classes(self): 15 checked=0 16 for p in range(2,6): 17 lo,hi=2**(p-1),2**p-1 18 values=[dyadic(m,-6) for m in range(lo)] 19 values += [dyadic(m,e) for e in range(-6,4) for m in range(lo,hi+1)] 20 virtual=dyadic(2**p,3) 21 def rounded(x): 22 i=bisect_left(values,x) 23 if i==len(values): 24 return i if x >= (values[-1]+virtual)/2 else i-1 25 if values[i]==x or i==0: return i 26 below,above=x-values[i-1],values[i]-x 27 return i-1 if below<above or (below==above and (i-1)%2==0) else i 28 for a in range(lo,hi+1): 29 for b in range(lo,hi+1): 30 for gap in range(p+2,p+5): 31 for e in range(-p-7,6): 32 for sign in [-1,1]: 33 actual=dyadic(a,e)+sign*dyadic(b,e-gap) 34 surrogate=dyadic(8*a+sign,e-3) 35 self.assertEqual(rounded(actual),rounded(surrogate)) 36 checked+=1 37 self.assertGreater(checked,30000) 38 39 def test_discarding_residual_does_not_preserve_midpoints(self): 40 add=(1177,55,2**52,2**52) 41 sub=(1178,55,3*2**51,2**52) 42 self.assertEqual(nearest(exact(add)),(1,True,True)) 43 self.assertEqual(nearest(dyadic(add[2],add[0]-BIAS))[0],0) 44 self.assertEqual(nearest(exact(sub,True)),(1,True,True)) 45 self.assertEqual(nearest(dyadic(sub[2],sub[0]-BIAS))[0],2) 46 47 def test_threshold_is_strict(self): 48 # At gap 54 the decrement can exceed the midpoint below a power of two. 49 row=(2252,54,2**52,2**53-1) 50 self.assertEqual(nearest(exact(row,True))[0],0x3fefffffffffffff) 51 self.assertEqual(nearest(dyadic(8*row[2]-1,row[0]-BIAS-3))[0],0x3ff0000000000000) 52 53 def test_surrogate_on_full_binary64_far_corpus(self): 54 for scale,gap,a,b in cases(): 55 if gap<55: continue 56 for sub in [False,True]: 57 self.assertEqual(nearest(exact((scale,gap,a,b),sub)), 58 nearest(dyadic(8*a+(-1 if sub else 1),scale-BIAS-3))) 59 60 @unittest.skipUnless(sys.float_info.radix==2 and sys.float_info.mant_dig==53, 61 'requires binary64 Python floats') 62 def test_exact_fraction_oracle_against_host(self): 63 for row in cases(): 64 for sub in [False,True]: 65 x=exact(row,sub) 66 try: f=float(x) 67 except OverflowError: f=math.inf 68 bits=int.from_bytes(struct.pack('>d',f),'big') 69 inexact=math.isinf(f) or value(bits)!=x 70 self.assertEqual(nearest(x),(bits,inexact,inexact and bits<2**52)) 71 72 73 if __name__=='__main__': unittest.main()