float_pipelines_oracle_test.py (1643B)
1 #!/usr/bin/env python3 2 """Independent binary64 checks of the finite, positive pipeline oracle.""" 3 import math 4 import random 5 import sys 6 import unittest 7 8 from float_pipelines import finish, operation 9 10 11 @unittest.skipUnless(sys.float_info.radix == 2 and sys.float_info.mant_dig == 53, 12 'requires a binary64 Python host for this independent check') 13 class PipelineOracleTests(unittest.TestCase): 14 def test_integer_conversion_and_inexact(self): 15 rng = random.Random(105106) 16 values = [0,1] 17 for width in range(1,161): 18 values += [(1 << width)-1,1 << width,(1 << width)+1,rng.getrandbits(width)] 19 for n in values: 20 shift,m,inexact = finish(n) 21 self.assertLessEqual(m.bit_length(),53) 22 self.assertEqual(m << shift,int(float(n))) 23 self.assertEqual(inexact,n != (m << shift)) 24 25 def test_normalized_product_chains(self): 26 rng = random.Random(5353) 27 for _ in range(256): 28 a,b = [rng.getrandbits(52)+(1 << 52) for _ in range(2)] 29 shift,m,_ = operation('Multiply',a,b) 30 self.assertEqual(math.ldexp(float(m),shift),float(a)*float(b)) 31 shift,m,_ = operation('Chain',a,b) 32 reference = float(a) 33 for _ in range(3): 34 reference *= float(b) 35 self.assertEqual(math.ldexp(float(m),shift),reference) 36 37 def test_rounding_carry(self): 38 shift,m,inexact = finish((1 << 54)-1) 39 self.assertEqual((shift,m,inexact),(2,1 << 52,True)) 40 self.assertEqual(finish(1 << 54),(2,1 << 52,False)) 41 42 43 if __name__ == '__main__': 44 unittest.main()