summaryrefslogtreecommitdiff
path: root/Lib/test/test_long.py
diff options
context:
space:
mode:
authorMark Dickinson <dickinsm@gmail.com>2009-04-20 21:13:33 +0000
committerMark Dickinson <dickinsm@gmail.com>2009-04-20 21:13:33 +0000
commitaddbe9e777b09562635f4acf1100b5edfbe7f972 (patch)
treea7ce2bba9916c8f3617503c48721e00302bd36e2 /Lib/test/test_long.py
parent75ab0ce8cdfad079fc75e34d712d1f8864d233fb (diff)
downloadcpython-addbe9e777b09562635f4acf1100b5edfbe7f972.tar.gz
Issue #3166: Make long -> float (and int -> float) conversions
correctly rounded, using round-half-to-even. This ensures that the value of float(n) doesn't depend on whether we're using 15-bit digits or 30-bit digits for Python longs.
Diffstat (limited to 'Lib/test/test_long.py')
-rw-r--r--Lib/test/test_long.py59
1 files changed, 59 insertions, 0 deletions
diff --git a/Lib/test/test_long.py b/Lib/test/test_long.py
index 1a0e33dd57..b41d270c18 100644
--- a/Lib/test/test_long.py
+++ b/Lib/test/test_long.py
@@ -645,6 +645,65 @@ class LongTest(unittest.TestCase):
else:
self.assertRaises(TypeError, pow,longx, longy, long(z))
+ @unittest.skipUnless(float.__getformat__("double").startswith("IEEE"),
+ "test requires IEEE 754 doubles")
+ def test_float_conversion(self):
+ import sys
+ DBL_MAX = sys.float_info.max
+ DBL_MAX_EXP = sys.float_info.max_exp
+ DBL_MANT_DIG = sys.float_info.mant_dig
+
+ exact_values = [0L, 1L, 2L,
+ long(2**53-3),
+ long(2**53-2),
+ long(2**53-1),
+ long(2**53),
+ long(2**53+2),
+ long(2**54-4),
+ long(2**54-2),
+ long(2**54),
+ long(2**54+4)]
+ for x in exact_values:
+ self.assertEqual(long(float(x)), x)
+ self.assertEqual(long(float(-x)), -x)
+
+ # test round-half-even
+ for x, y in [(1, 0), (2, 2), (3, 4), (4, 4), (5, 4), (6, 6), (7, 8)]:
+ for p in xrange(15):
+ self.assertEqual(long(float(2L**p*(2**53+x))), 2L**p*(2**53+y))
+
+ for x, y in [(0, 0), (1, 0), (2, 0), (3, 4), (4, 4), (5, 4), (6, 8),
+ (7, 8), (8, 8), (9, 8), (10, 8), (11, 12), (12, 12),
+ (13, 12), (14, 16), (15, 16)]:
+ for p in xrange(15):
+ self.assertEqual(long(float(2L**p*(2**54+x))), 2L**p*(2**54+y))
+
+ # behaviour near extremes of floating-point range
+ long_dbl_max = long(DBL_MAX)
+ top_power = 2**DBL_MAX_EXP
+ halfway = (long_dbl_max + top_power)/2
+ self.assertEqual(float(long_dbl_max), DBL_MAX)
+ self.assertEqual(float(long_dbl_max+1), DBL_MAX)
+ self.assertEqual(float(halfway-1), DBL_MAX)
+ self.assertRaises(OverflowError, float, halfway)
+ self.assertEqual(float(1-halfway), -DBL_MAX)
+ self.assertRaises(OverflowError, float, -halfway)
+ self.assertRaises(OverflowError, float, top_power-1)
+ self.assertRaises(OverflowError, float, top_power)
+ self.assertRaises(OverflowError, float, top_power+1)
+ self.assertRaises(OverflowError, float, 2*top_power-1)
+ self.assertRaises(OverflowError, float, 2*top_power)
+ self.assertRaises(OverflowError, float, top_power*top_power)
+
+ for p in xrange(100):
+ x = long(2**p * (2**53 + 1) + 1)
+ y = long(2**p * (2**53+ 2))
+ self.assertEqual(long(float(x)), y)
+
+ x = long(2**p * (2**53 + 1))
+ y = long(2**p * 2**53)
+ self.assertEqual(long(float(x)), y)
+
def test_float_overflow(self):
import math