blob: 5bf1d314e910edd1447469c82abe35349c1006cc [file] [log] [blame]
Michael W. Hudsonba283e22005-05-27 15:23:20 +00001
2import unittest, struct
Christian Heimes284d9272007-12-10 22:28:56 +00003import os
Michael W. Hudsonba283e22005-05-27 15:23:20 +00004from test import test_support
Christian Heimes6f341092008-04-18 23:13:07 +00005import math
Mark Dickinson7103aa42008-07-15 19:08:33 +00006from math import isinf, isnan, copysign, ldexp
Christian Heimes6f341092008-04-18 23:13:07 +00007import operator
Mark Dickinsonbd15a062009-11-18 19:33:35 +00008import random
9import fractions
10import sys
Benjamin Petersonf0506482015-03-06 09:08:44 -050011import time
Michael W. Hudsonba283e22005-05-27 15:23:20 +000012
Christian Heimes6f341092008-04-18 23:13:07 +000013INF = float("inf")
14NAN = float("nan")
Christian Heimes0a8143f2007-12-18 23:22:54 +000015
Benjamin Peterson0df5a852010-07-02 23:05:27 +000016have_getformat = hasattr(float, "__getformat__")
17requires_getformat = unittest.skipUnless(have_getformat,
18 "requires __getformat__")
19requires_setformat = unittest.skipUnless(hasattr(float, "__setformat__"),
20 "requires __setformat__")
Mark Dickinson99d652e2009-12-30 12:12:23 +000021# decorator for skipping tests on non-IEEE 754 platforms
Benjamin Peterson0df5a852010-07-02 23:05:27 +000022requires_IEEE_754 = unittest.skipUnless(have_getformat and
Mark Dickinson99d652e2009-12-30 12:12:23 +000023 float.__getformat__("double").startswith("IEEE"),
24 "test requires IEEE 754 doubles")
25
Mark Dickinson61a0d052009-04-29 21:57:15 +000026#locate file with float format test values
27test_dir = os.path.dirname(__file__) or os.curdir
28format_testfile = os.path.join(test_dir, 'formatfloat_testcases.txt')
29
Benjamin Peterson979395b2008-05-03 21:35:18 +000030class GeneralFloatCases(unittest.TestCase):
31
32 def test_float(self):
33 self.assertEqual(float(3.14), 3.14)
34 self.assertEqual(float(314), 314.0)
35 self.assertEqual(float(314L), 314.0)
36 self.assertEqual(float(" 3.14 "), 3.14)
37 self.assertRaises(ValueError, float, " 0x3.1 ")
38 self.assertRaises(ValueError, float, " -0x3.p-1 ")
39 self.assertRaises(ValueError, float, " +0x3.p-1 ")
40 self.assertRaises(ValueError, float, "++3.14")
41 self.assertRaises(ValueError, float, "+-3.14")
42 self.assertRaises(ValueError, float, "-+3.14")
43 self.assertRaises(ValueError, float, "--3.14")
Mark Dickinson876473b2010-02-12 21:16:38 +000044 # check that we don't accept alternate exponent markers
45 self.assertRaises(ValueError, float, "-1.7d29")
46 self.assertRaises(ValueError, float, "3D-14")
Amaury Forgeot d'Arcfeb8cad2008-09-06 20:53:51 +000047 if test_support.have_unicode:
Benjamin Peterson979395b2008-05-03 21:35:18 +000048 self.assertEqual(float(unicode(" 3.14 ")), 3.14)
49 self.assertEqual(float(unicode(" \u0663.\u0661\u0664 ",'raw-unicode-escape')), 3.14)
Benjamin Peterson979395b2008-05-03 21:35:18 +000050
Mark Dickinson53e9fa42009-10-27 22:09:33 +000051 # extra long strings should no longer be a problem
52 # (in 2.6, long unicode inputs to float raised ValueError)
53 float('.' + '1'*1000)
54 float(unicode('.' + '1'*1000))
55
Mark Dickinson874d59e2011-03-26 12:18:00 +000056 def check_conversion_to_int(self, x):
57 """Check that int(x) has the correct value and type, for a float x."""
58 n = int(x)
59 if x >= 0.0:
60 # x >= 0 and n = int(x) ==> n <= x < n + 1
61 self.assertLessEqual(n, x)
62 self.assertLess(x, n + 1)
63 else:
64 # x < 0 and n = int(x) ==> n >= x > n - 1
65 self.assertGreaterEqual(n, x)
66 self.assertGreater(x, n - 1)
67
68 # Result should be an int if within range, else a long.
69 if -sys.maxint-1 <= n <= sys.maxint:
70 self.assertEqual(type(n), int)
71 else:
72 self.assertEqual(type(n), long)
73
74 # Double check.
75 self.assertEqual(type(int(n)), type(n))
76
77 def test_conversion_to_int(self):
78 # Check that floats within the range of an int convert to type
79 # int, not long. (issue #11144.)
80 boundary = float(sys.maxint + 1)
81 epsilon = 2**-sys.float_info.mant_dig * boundary
82
83 # These 2 floats are either side of the positive int/long boundary on
84 # both 32-bit and 64-bit systems.
85 self.check_conversion_to_int(boundary - epsilon)
86 self.check_conversion_to_int(boundary)
87
88 # These floats are either side of the negative long/int boundary on
89 # 64-bit systems...
90 self.check_conversion_to_int(-boundary - 2*epsilon)
91 self.check_conversion_to_int(-boundary)
92
93 # ... and these ones are either side of the negative long/int
94 # boundary on 32-bit systems.
95 self.check_conversion_to_int(-boundary - 1.0)
96 self.check_conversion_to_int(-boundary - 1.0 + 2*epsilon)
97
Benjamin Peterson979395b2008-05-03 21:35:18 +000098 @test_support.run_with_locale('LC_NUMERIC', 'fr_FR', 'de_DE')
99 def test_float_with_comma(self):
100 # set locale to something that doesn't use '.' for the decimal point
101 # float must not accept the locale specific decimal point but
Ezio Melottic2077b02011-03-16 12:34:31 +0200102 # it still has to accept the normal python syntax
Benjamin Peterson979395b2008-05-03 21:35:18 +0000103 import locale
104 if not locale.localeconv()['decimal_point'] == ',':
Zachary Ware1f702212013-12-10 14:09:20 -0600105 self.skipTest('decimal_point is not ","')
Benjamin Peterson979395b2008-05-03 21:35:18 +0000106
107 self.assertEqual(float(" 3.14 "), 3.14)
108 self.assertEqual(float("+3.14 "), 3.14)
109 self.assertEqual(float("-3.14 "), -3.14)
110 self.assertEqual(float(".14 "), .14)
111 self.assertEqual(float("3. "), 3.0)
112 self.assertEqual(float("3.e3 "), 3000.0)
113 self.assertEqual(float("3.2e3 "), 3200.0)
114 self.assertEqual(float("2.5e-1 "), 0.25)
115 self.assertEqual(float("5e-1"), 0.5)
116 self.assertRaises(ValueError, float, " 3,14 ")
117 self.assertRaises(ValueError, float, " +3,14 ")
118 self.assertRaises(ValueError, float, " -3,14 ")
119 self.assertRaises(ValueError, float, " 0x3.1 ")
120 self.assertRaises(ValueError, float, " -0x3.p-1 ")
121 self.assertRaises(ValueError, float, " +0x3.p-1 ")
122 self.assertEqual(float(" 25.e-1 "), 2.5)
Benjamin Petersona853a892008-09-06 23:19:15 +0000123 self.assertEqual(test_support.fcmp(float(" .25e-1 "), .025), 0)
Benjamin Peterson979395b2008-05-03 21:35:18 +0000124
125 def test_floatconversion(self):
126 # Make sure that calls to __float__() work properly
127 class Foo0:
128 def __float__(self):
129 return 42.
130
131 class Foo1(object):
132 def __float__(self):
133 return 42.
134
135 class Foo2(float):
136 def __float__(self):
137 return 42.
138
139 class Foo3(float):
140 def __new__(cls, value=0.):
141 return float.__new__(cls, 2*value)
142
143 def __float__(self):
144 return self
145
146 class Foo4(float):
147 def __float__(self):
148 return 42
149
Benjamin Peterson99d36f12009-04-15 21:26:36 +0000150 # Issue 5759: __float__ not called on str subclasses (though it is on
151 # unicode subclasses).
152 class FooStr(str):
153 def __float__(self):
154 return float(str(self)) + 1
155
156 class FooUnicode(unicode):
157 def __float__(self):
158 return float(unicode(self)) + 1
159
Benjamin Peterson979395b2008-05-03 21:35:18 +0000160 self.assertAlmostEqual(float(Foo0()), 42.)
161 self.assertAlmostEqual(float(Foo1()), 42.)
162 self.assertAlmostEqual(float(Foo2()), 42.)
163 self.assertAlmostEqual(float(Foo3(21)), 42.)
164 self.assertRaises(TypeError, float, Foo4(42))
Benjamin Peterson99d36f12009-04-15 21:26:36 +0000165 self.assertAlmostEqual(float(FooUnicode('8')), 9.)
166 self.assertAlmostEqual(float(FooStr('8')), 9.)
Benjamin Peterson979395b2008-05-03 21:35:18 +0000167
Benjamin Petersonf0506482015-03-06 09:08:44 -0500168 class Foo5:
169 def __float__(self):
170 return ""
171 self.assertRaises(TypeError, time.sleep, Foo5())
172
Benjamin Petersone96102b2011-10-28 19:42:48 -0400173 def test_is_integer(self):
174 self.assertFalse((1.1).is_integer())
175 self.assertTrue((1.).is_integer())
176 self.assertFalse(float("nan").is_integer())
177 self.assertFalse(float("inf").is_integer())
178
Benjamin Peterson979395b2008-05-03 21:35:18 +0000179 def test_floatasratio(self):
180 for f, ratio in [
181 (0.875, (7, 8)),
182 (-0.875, (-7, 8)),
183 (0.0, (0, 1)),
184 (11.5, (23, 2)),
185 ]:
186 self.assertEqual(f.as_integer_ratio(), ratio)
187
188 for i in range(10000):
189 f = random.random()
190 f *= 10 ** random.randint(-100, 100)
191 n, d = f.as_integer_ratio()
192 self.assertEqual(float(n).__truediv__(d), f)
193
194 R = fractions.Fraction
195 self.assertEqual(R(0, 1),
196 R(*float(0.0).as_integer_ratio()))
197 self.assertEqual(R(5, 2),
198 R(*float(2.5).as_integer_ratio()))
199 self.assertEqual(R(1, 2),
200 R(*float(0.5).as_integer_ratio()))
201 self.assertEqual(R(4728779608739021, 2251799813685248),
202 R(*float(2.1).as_integer_ratio()))
203 self.assertEqual(R(-4728779608739021, 2251799813685248),
204 R(*float(-2.1).as_integer_ratio()))
205 self.assertEqual(R(-2100, 1),
206 R(*float(-2100.0).as_integer_ratio()))
207
208 self.assertRaises(OverflowError, float('inf').as_integer_ratio)
209 self.assertRaises(OverflowError, float('-inf').as_integer_ratio)
210 self.assertRaises(ValueError, float('nan').as_integer_ratio)
211
Mark Dickinson99d652e2009-12-30 12:12:23 +0000212 def assertEqualAndEqualSign(self, a, b):
213 # fail unless a == b and a and b have the same sign bit;
214 # the only difference from assertEqual is that this test
Ezio Melottic2077b02011-03-16 12:34:31 +0200215 # distinguishes -0.0 and 0.0.
Mark Dickinson99d652e2009-12-30 12:12:23 +0000216 self.assertEqual((a, copysign(1.0, a)), (b, copysign(1.0, b)))
217
218 @requires_IEEE_754
Mark Dickinsonecf8ec62010-12-04 12:30:41 +0000219 def test_float_mod(self):
220 # Check behaviour of % operator for IEEE 754 special cases.
221 # In particular, check signs of zeros.
222 mod = operator.mod
223
224 self.assertEqualAndEqualSign(mod(-1.0, 1.0), 0.0)
225 self.assertEqualAndEqualSign(mod(-1e-100, 1.0), 1.0)
226 self.assertEqualAndEqualSign(mod(-0.0, 1.0), 0.0)
227 self.assertEqualAndEqualSign(mod(0.0, 1.0), 0.0)
228 self.assertEqualAndEqualSign(mod(1e-100, 1.0), 1e-100)
229 self.assertEqualAndEqualSign(mod(1.0, 1.0), 0.0)
230
231 self.assertEqualAndEqualSign(mod(-1.0, -1.0), -0.0)
232 self.assertEqualAndEqualSign(mod(-1e-100, -1.0), -1e-100)
233 self.assertEqualAndEqualSign(mod(-0.0, -1.0), -0.0)
234 self.assertEqualAndEqualSign(mod(0.0, -1.0), -0.0)
235 self.assertEqualAndEqualSign(mod(1e-100, -1.0), -1.0)
236 self.assertEqualAndEqualSign(mod(1.0, -1.0), -0.0)
237
238 @requires_IEEE_754
Mark Dickinson99d652e2009-12-30 12:12:23 +0000239 def test_float_pow(self):
240 # test builtin pow and ** operator for IEEE 754 special cases.
241 # Special cases taken from section F.9.4.4 of the C99 specification
242
243 for pow_op in pow, operator.pow:
244 # x**NAN is NAN for any x except 1
245 self.assertTrue(isnan(pow_op(-INF, NAN)))
246 self.assertTrue(isnan(pow_op(-2.0, NAN)))
247 self.assertTrue(isnan(pow_op(-1.0, NAN)))
248 self.assertTrue(isnan(pow_op(-0.5, NAN)))
249 self.assertTrue(isnan(pow_op(-0.0, NAN)))
250 self.assertTrue(isnan(pow_op(0.0, NAN)))
251 self.assertTrue(isnan(pow_op(0.5, NAN)))
252 self.assertTrue(isnan(pow_op(2.0, NAN)))
253 self.assertTrue(isnan(pow_op(INF, NAN)))
254 self.assertTrue(isnan(pow_op(NAN, NAN)))
255
256 # NAN**y is NAN for any y except +-0
257 self.assertTrue(isnan(pow_op(NAN, -INF)))
258 self.assertTrue(isnan(pow_op(NAN, -2.0)))
259 self.assertTrue(isnan(pow_op(NAN, -1.0)))
260 self.assertTrue(isnan(pow_op(NAN, -0.5)))
261 self.assertTrue(isnan(pow_op(NAN, 0.5)))
262 self.assertTrue(isnan(pow_op(NAN, 1.0)))
263 self.assertTrue(isnan(pow_op(NAN, 2.0)))
264 self.assertTrue(isnan(pow_op(NAN, INF)))
265
266 # (+-0)**y raises ZeroDivisionError for y a negative odd integer
267 self.assertRaises(ZeroDivisionError, pow_op, -0.0, -1.0)
268 self.assertRaises(ZeroDivisionError, pow_op, 0.0, -1.0)
269
270 # (+-0)**y raises ZeroDivisionError for y finite and negative
271 # but not an odd integer
272 self.assertRaises(ZeroDivisionError, pow_op, -0.0, -2.0)
273 self.assertRaises(ZeroDivisionError, pow_op, -0.0, -0.5)
274 self.assertRaises(ZeroDivisionError, pow_op, 0.0, -2.0)
275 self.assertRaises(ZeroDivisionError, pow_op, 0.0, -0.5)
276
277 # (+-0)**y is +-0 for y a positive odd integer
278 self.assertEqualAndEqualSign(pow_op(-0.0, 1.0), -0.0)
279 self.assertEqualAndEqualSign(pow_op(0.0, 1.0), 0.0)
280
281 # (+-0)**y is 0 for y finite and positive but not an odd integer
282 self.assertEqualAndEqualSign(pow_op(-0.0, 0.5), 0.0)
283 self.assertEqualAndEqualSign(pow_op(-0.0, 2.0), 0.0)
284 self.assertEqualAndEqualSign(pow_op(0.0, 0.5), 0.0)
285 self.assertEqualAndEqualSign(pow_op(0.0, 2.0), 0.0)
286
287 # (-1)**+-inf is 1
288 self.assertEqualAndEqualSign(pow_op(-1.0, -INF), 1.0)
289 self.assertEqualAndEqualSign(pow_op(-1.0, INF), 1.0)
290
291 # 1**y is 1 for any y, even if y is an infinity or nan
292 self.assertEqualAndEqualSign(pow_op(1.0, -INF), 1.0)
293 self.assertEqualAndEqualSign(pow_op(1.0, -2.0), 1.0)
294 self.assertEqualAndEqualSign(pow_op(1.0, -1.0), 1.0)
295 self.assertEqualAndEqualSign(pow_op(1.0, -0.5), 1.0)
296 self.assertEqualAndEqualSign(pow_op(1.0, -0.0), 1.0)
297 self.assertEqualAndEqualSign(pow_op(1.0, 0.0), 1.0)
298 self.assertEqualAndEqualSign(pow_op(1.0, 0.5), 1.0)
299 self.assertEqualAndEqualSign(pow_op(1.0, 1.0), 1.0)
300 self.assertEqualAndEqualSign(pow_op(1.0, 2.0), 1.0)
301 self.assertEqualAndEqualSign(pow_op(1.0, INF), 1.0)
302 self.assertEqualAndEqualSign(pow_op(1.0, NAN), 1.0)
303
304 # x**+-0 is 1 for any x, even if x is a zero, infinity, or nan
305 self.assertEqualAndEqualSign(pow_op(-INF, 0.0), 1.0)
306 self.assertEqualAndEqualSign(pow_op(-2.0, 0.0), 1.0)
307 self.assertEqualAndEqualSign(pow_op(-1.0, 0.0), 1.0)
308 self.assertEqualAndEqualSign(pow_op(-0.5, 0.0), 1.0)
309 self.assertEqualAndEqualSign(pow_op(-0.0, 0.0), 1.0)
310 self.assertEqualAndEqualSign(pow_op(0.0, 0.0), 1.0)
311 self.assertEqualAndEqualSign(pow_op(0.5, 0.0), 1.0)
312 self.assertEqualAndEqualSign(pow_op(1.0, 0.0), 1.0)
313 self.assertEqualAndEqualSign(pow_op(2.0, 0.0), 1.0)
314 self.assertEqualAndEqualSign(pow_op(INF, 0.0), 1.0)
315 self.assertEqualAndEqualSign(pow_op(NAN, 0.0), 1.0)
316 self.assertEqualAndEqualSign(pow_op(-INF, -0.0), 1.0)
317 self.assertEqualAndEqualSign(pow_op(-2.0, -0.0), 1.0)
318 self.assertEqualAndEqualSign(pow_op(-1.0, -0.0), 1.0)
319 self.assertEqualAndEqualSign(pow_op(-0.5, -0.0), 1.0)
320 self.assertEqualAndEqualSign(pow_op(-0.0, -0.0), 1.0)
321 self.assertEqualAndEqualSign(pow_op(0.0, -0.0), 1.0)
322 self.assertEqualAndEqualSign(pow_op(0.5, -0.0), 1.0)
323 self.assertEqualAndEqualSign(pow_op(1.0, -0.0), 1.0)
324 self.assertEqualAndEqualSign(pow_op(2.0, -0.0), 1.0)
325 self.assertEqualAndEqualSign(pow_op(INF, -0.0), 1.0)
326 self.assertEqualAndEqualSign(pow_op(NAN, -0.0), 1.0)
327
328 # x**y raises ValueError for finite negative x and non-integral y
329 self.assertRaises(ValueError, pow_op, -2.0, -0.5)
330 self.assertRaises(ValueError, pow_op, -2.0, 0.5)
331 self.assertRaises(ValueError, pow_op, -1.0, -0.5)
332 self.assertRaises(ValueError, pow_op, -1.0, 0.5)
333 self.assertRaises(ValueError, pow_op, -0.5, -0.5)
334 self.assertRaises(ValueError, pow_op, -0.5, 0.5)
335
336 # x**-INF is INF for abs(x) < 1
337 self.assertEqualAndEqualSign(pow_op(-0.5, -INF), INF)
338 self.assertEqualAndEqualSign(pow_op(-0.0, -INF), INF)
339 self.assertEqualAndEqualSign(pow_op(0.0, -INF), INF)
340 self.assertEqualAndEqualSign(pow_op(0.5, -INF), INF)
341
342 # x**-INF is 0 for abs(x) > 1
343 self.assertEqualAndEqualSign(pow_op(-INF, -INF), 0.0)
344 self.assertEqualAndEqualSign(pow_op(-2.0, -INF), 0.0)
345 self.assertEqualAndEqualSign(pow_op(2.0, -INF), 0.0)
346 self.assertEqualAndEqualSign(pow_op(INF, -INF), 0.0)
347
348 # x**INF is 0 for abs(x) < 1
349 self.assertEqualAndEqualSign(pow_op(-0.5, INF), 0.0)
350 self.assertEqualAndEqualSign(pow_op(-0.0, INF), 0.0)
351 self.assertEqualAndEqualSign(pow_op(0.0, INF), 0.0)
352 self.assertEqualAndEqualSign(pow_op(0.5, INF), 0.0)
353
354 # x**INF is INF for abs(x) > 1
355 self.assertEqualAndEqualSign(pow_op(-INF, INF), INF)
356 self.assertEqualAndEqualSign(pow_op(-2.0, INF), INF)
357 self.assertEqualAndEqualSign(pow_op(2.0, INF), INF)
358 self.assertEqualAndEqualSign(pow_op(INF, INF), INF)
359
360 # (-INF)**y is -0.0 for y a negative odd integer
361 self.assertEqualAndEqualSign(pow_op(-INF, -1.0), -0.0)
362
363 # (-INF)**y is 0.0 for y negative but not an odd integer
364 self.assertEqualAndEqualSign(pow_op(-INF, -0.5), 0.0)
365 self.assertEqualAndEqualSign(pow_op(-INF, -2.0), 0.0)
366
367 # (-INF)**y is -INF for y a positive odd integer
368 self.assertEqualAndEqualSign(pow_op(-INF, 1.0), -INF)
369
370 # (-INF)**y is INF for y positive but not an odd integer
371 self.assertEqualAndEqualSign(pow_op(-INF, 0.5), INF)
372 self.assertEqualAndEqualSign(pow_op(-INF, 2.0), INF)
373
374 # INF**y is INF for y positive
375 self.assertEqualAndEqualSign(pow_op(INF, 0.5), INF)
376 self.assertEqualAndEqualSign(pow_op(INF, 1.0), INF)
377 self.assertEqualAndEqualSign(pow_op(INF, 2.0), INF)
378
379 # INF**y is 0.0 for y negative
380 self.assertEqualAndEqualSign(pow_op(INF, -2.0), 0.0)
381 self.assertEqualAndEqualSign(pow_op(INF, -1.0), 0.0)
382 self.assertEqualAndEqualSign(pow_op(INF, -0.5), 0.0)
383
384 # basic checks not covered by the special cases above
385 self.assertEqualAndEqualSign(pow_op(-2.0, -2.0), 0.25)
386 self.assertEqualAndEqualSign(pow_op(-2.0, -1.0), -0.5)
387 self.assertEqualAndEqualSign(pow_op(-2.0, -0.0), 1.0)
388 self.assertEqualAndEqualSign(pow_op(-2.0, 0.0), 1.0)
389 self.assertEqualAndEqualSign(pow_op(-2.0, 1.0), -2.0)
390 self.assertEqualAndEqualSign(pow_op(-2.0, 2.0), 4.0)
391 self.assertEqualAndEqualSign(pow_op(-1.0, -2.0), 1.0)
392 self.assertEqualAndEqualSign(pow_op(-1.0, -1.0), -1.0)
393 self.assertEqualAndEqualSign(pow_op(-1.0, -0.0), 1.0)
394 self.assertEqualAndEqualSign(pow_op(-1.0, 0.0), 1.0)
395 self.assertEqualAndEqualSign(pow_op(-1.0, 1.0), -1.0)
396 self.assertEqualAndEqualSign(pow_op(-1.0, 2.0), 1.0)
397 self.assertEqualAndEqualSign(pow_op(2.0, -2.0), 0.25)
398 self.assertEqualAndEqualSign(pow_op(2.0, -1.0), 0.5)
399 self.assertEqualAndEqualSign(pow_op(2.0, -0.0), 1.0)
400 self.assertEqualAndEqualSign(pow_op(2.0, 0.0), 1.0)
401 self.assertEqualAndEqualSign(pow_op(2.0, 1.0), 2.0)
402 self.assertEqualAndEqualSign(pow_op(2.0, 2.0), 4.0)
403
404 # 1 ** large and -1 ** large; some libms apparently
405 # have problems with these
406 self.assertEqualAndEqualSign(pow_op(1.0, -1e100), 1.0)
407 self.assertEqualAndEqualSign(pow_op(1.0, 1e100), 1.0)
408 self.assertEqualAndEqualSign(pow_op(-1.0, -1e100), 1.0)
409 self.assertEqualAndEqualSign(pow_op(-1.0, 1e100), 1.0)
410
411 # check sign for results that underflow to 0
412 self.assertEqualAndEqualSign(pow_op(-2.0, -2000.0), 0.0)
413 self.assertRaises(ValueError, pow_op, -2.0, -2000.5)
414 self.assertEqualAndEqualSign(pow_op(-2.0, -2001.0), -0.0)
415 self.assertEqualAndEqualSign(pow_op(2.0, -2000.0), 0.0)
416 self.assertEqualAndEqualSign(pow_op(2.0, -2000.5), 0.0)
417 self.assertEqualAndEqualSign(pow_op(2.0, -2001.0), 0.0)
418 self.assertEqualAndEqualSign(pow_op(-0.5, 2000.0), 0.0)
419 self.assertRaises(ValueError, pow_op, -0.5, 2000.5)
420 self.assertEqualAndEqualSign(pow_op(-0.5, 2001.0), -0.0)
421 self.assertEqualAndEqualSign(pow_op(0.5, 2000.0), 0.0)
422 self.assertEqualAndEqualSign(pow_op(0.5, 2000.5), 0.0)
423 self.assertEqualAndEqualSign(pow_op(0.5, 2001.0), 0.0)
424
425 # check we don't raise an exception for subnormal results,
426 # and validate signs. Tests currently disabled, since
427 # they fail on systems where a subnormal result from pow
428 # is flushed to zero (e.g. Debian/ia64.)
429 #self.assertTrue(0.0 < pow_op(0.5, 1048) < 1e-315)
430 #self.assertTrue(0.0 < pow_op(-0.5, 1048) < 1e-315)
431 #self.assertTrue(0.0 < pow_op(0.5, 1047) < 1e-315)
432 #self.assertTrue(0.0 > pow_op(-0.5, 1047) > -1e-315)
433 #self.assertTrue(0.0 < pow_op(2.0, -1048) < 1e-315)
434 #self.assertTrue(0.0 < pow_op(-2.0, -1048) < 1e-315)
435 #self.assertTrue(0.0 < pow_op(2.0, -1047) < 1e-315)
436 #self.assertTrue(0.0 > pow_op(-2.0, -1047) > -1e-315)
437
438
Benjamin Peterson0df5a852010-07-02 23:05:27 +0000439@requires_setformat
Michael W. Hudsonba283e22005-05-27 15:23:20 +0000440class FormatFunctionsTestCase(unittest.TestCase):
441
442 def setUp(self):
443 self.save_formats = {'double':float.__getformat__('double'),
444 'float':float.__getformat__('float')}
445
446 def tearDown(self):
447 float.__setformat__('double', self.save_formats['double'])
448 float.__setformat__('float', self.save_formats['float'])
449
450 def test_getformat(self):
Ezio Melottiaa980582010-01-23 23:04:36 +0000451 self.assertIn(float.__getformat__('double'),
452 ['unknown', 'IEEE, big-endian', 'IEEE, little-endian'])
453 self.assertIn(float.__getformat__('float'),
454 ['unknown', 'IEEE, big-endian', 'IEEE, little-endian'])
Michael W. Hudsonba283e22005-05-27 15:23:20 +0000455 self.assertRaises(ValueError, float.__getformat__, 'chicken')
456 self.assertRaises(TypeError, float.__getformat__, 1)
457
458 def test_setformat(self):
459 for t in 'double', 'float':
460 float.__setformat__(t, 'unknown')
461 if self.save_formats[t] == 'IEEE, big-endian':
462 self.assertRaises(ValueError, float.__setformat__,
463 t, 'IEEE, little-endian')
464 elif self.save_formats[t] == 'IEEE, little-endian':
465 self.assertRaises(ValueError, float.__setformat__,
466 t, 'IEEE, big-endian')
467 else:
468 self.assertRaises(ValueError, float.__setformat__,
469 t, 'IEEE, big-endian')
470 self.assertRaises(ValueError, float.__setformat__,
471 t, 'IEEE, little-endian')
472 self.assertRaises(ValueError, float.__setformat__,
473 t, 'chicken')
474 self.assertRaises(ValueError, float.__setformat__,
475 'chicken', 'unknown')
476
477BE_DOUBLE_INF = '\x7f\xf0\x00\x00\x00\x00\x00\x00'
478LE_DOUBLE_INF = ''.join(reversed(BE_DOUBLE_INF))
479BE_DOUBLE_NAN = '\x7f\xf8\x00\x00\x00\x00\x00\x00'
480LE_DOUBLE_NAN = ''.join(reversed(BE_DOUBLE_NAN))
481
482BE_FLOAT_INF = '\x7f\x80\x00\x00'
483LE_FLOAT_INF = ''.join(reversed(BE_FLOAT_INF))
484BE_FLOAT_NAN = '\x7f\xc0\x00\x00'
485LE_FLOAT_NAN = ''.join(reversed(BE_FLOAT_NAN))
486
487# on non-IEEE platforms, attempting to unpack a bit pattern
488# representing an infinity or a NaN should raise an exception.
489
Benjamin Peterson0df5a852010-07-02 23:05:27 +0000490@requires_setformat
Michael W. Hudsonba283e22005-05-27 15:23:20 +0000491class UnknownFormatTestCase(unittest.TestCase):
492 def setUp(self):
493 self.save_formats = {'double':float.__getformat__('double'),
494 'float':float.__getformat__('float')}
495 float.__setformat__('double', 'unknown')
496 float.__setformat__('float', 'unknown')
Tim Peters5d36a552005-06-03 22:40:27 +0000497
Michael W. Hudsonba283e22005-05-27 15:23:20 +0000498 def tearDown(self):
499 float.__setformat__('double', self.save_formats['double'])
500 float.__setformat__('float', self.save_formats['float'])
501
502 def test_double_specials_dont_unpack(self):
503 for fmt, data in [('>d', BE_DOUBLE_INF),
504 ('>d', BE_DOUBLE_NAN),
505 ('<d', LE_DOUBLE_INF),
506 ('<d', LE_DOUBLE_NAN)]:
507 self.assertRaises(ValueError, struct.unpack, fmt, data)
508
509 def test_float_specials_dont_unpack(self):
510 for fmt, data in [('>f', BE_FLOAT_INF),
511 ('>f', BE_FLOAT_NAN),
512 ('<f', LE_FLOAT_INF),
513 ('<f', LE_FLOAT_NAN)]:
514 self.assertRaises(ValueError, struct.unpack, fmt, data)
515
516
517# on an IEEE platform, all we guarantee is that bit patterns
518# representing infinities or NaNs do not raise an exception; all else
519# is accident (today).
Alex Martellid8672aa2007-08-22 21:14:17 +0000520# let's also try to guarantee that -0.0 and 0.0 don't get confused.
Michael W. Hudsonba283e22005-05-27 15:23:20 +0000521
522class IEEEFormatTestCase(unittest.TestCase):
Michael W. Hudsonba283e22005-05-27 15:23:20 +0000523
Benjamin Peterson0df5a852010-07-02 23:05:27 +0000524 @requires_IEEE_754
525 def test_double_specials_do_unpack(self):
526 for fmt, data in [('>d', BE_DOUBLE_INF),
527 ('>d', BE_DOUBLE_NAN),
528 ('<d', LE_DOUBLE_INF),
529 ('<d', LE_DOUBLE_NAN)]:
530 struct.unpack(fmt, data)
Michael W. Hudsonba283e22005-05-27 15:23:20 +0000531
Benjamin Peterson0df5a852010-07-02 23:05:27 +0000532 @requires_IEEE_754
533 def test_float_specials_do_unpack(self):
534 for fmt, data in [('>f', BE_FLOAT_INF),
535 ('>f', BE_FLOAT_NAN),
536 ('<f', LE_FLOAT_INF),
537 ('<f', LE_FLOAT_NAN)]:
538 struct.unpack(fmt, data)
Alex Martellid8672aa2007-08-22 21:14:17 +0000539
Benjamin Peterson0df5a852010-07-02 23:05:27 +0000540 @requires_IEEE_754
541 def test_negative_zero(self):
542 def pos_pos():
543 return 0.0, math.atan2(0.0, -1)
544 def pos_neg():
545 return 0.0, math.atan2(-0.0, -1)
546 def neg_pos():
547 return -0.0, math.atan2(0.0, -1)
548 def neg_neg():
549 return -0.0, math.atan2(-0.0, -1)
Ezio Melotti2623a372010-11-21 13:34:58 +0000550 self.assertEqual(pos_pos(), neg_pos())
551 self.assertEqual(pos_neg(), neg_neg())
Benjamin Peterson0df5a852010-07-02 23:05:27 +0000552
553 @requires_IEEE_754
554 def test_underflow_sign(self):
555 # check that -1e-1000 gives -0.0, not 0.0
Ezio Melotti2623a372010-11-21 13:34:58 +0000556 self.assertEqual(math.atan2(-1e-1000, -1), math.atan2(-0.0, -1))
557 self.assertEqual(math.atan2(float('-1e-1000'), -1),
558 math.atan2(-0.0, -1))
Michael W. Hudsonba283e22005-05-27 15:23:20 +0000559
Eric Smitha985a3a2009-05-05 18:26:08 +0000560 def test_format(self):
561 # these should be rewritten to use both format(x, spec) and
562 # x.__format__(spec)
563
564 self.assertEqual(format(0.0, 'f'), '0.000000')
565
566 # the default is 'g', except for empty format spec
567 self.assertEqual(format(0.0, ''), '0.0')
568 self.assertEqual(format(0.01, ''), '0.01')
569 self.assertEqual(format(0.01, 'g'), '0.01')
570
571 # empty presentation type should format in the same way as str
572 # (issue 5920)
573 x = 100/7.
574 self.assertEqual(format(x, ''), str(x))
575 self.assertEqual(format(x, '-'), str(x))
576 self.assertEqual(format(x, '>'), str(x))
577 self.assertEqual(format(x, '2'), str(x))
578
579 self.assertEqual(format(1.0, 'f'), '1.000000')
580
581 self.assertEqual(format(-1.0, 'f'), '-1.000000')
582
583 self.assertEqual(format( 1.0, ' f'), ' 1.000000')
584 self.assertEqual(format(-1.0, ' f'), '-1.000000')
585 self.assertEqual(format( 1.0, '+f'), '+1.000000')
586 self.assertEqual(format(-1.0, '+f'), '-1.000000')
587
588 # % formatting
589 self.assertEqual(format(-1.0, '%'), '-100.000000%')
590
591 # conversion to string should fail
592 self.assertRaises(ValueError, format, 3.0, "s")
593
594 # other format specifiers shouldn't work on floats,
595 # in particular int specifiers
596 for format_spec in ([chr(x) for x in range(ord('a'), ord('z')+1)] +
597 [chr(x) for x in range(ord('A'), ord('Z')+1)]):
598 if not format_spec in 'eEfFgGn%':
599 self.assertRaises(ValueError, format, 0.0, format_spec)
600 self.assertRaises(ValueError, format, 1.0, format_spec)
601 self.assertRaises(ValueError, format, -1.0, format_spec)
602 self.assertRaises(ValueError, format, 1e100, format_spec)
603 self.assertRaises(ValueError, format, -1e100, format_spec)
604 self.assertRaises(ValueError, format, 1e-100, format_spec)
605 self.assertRaises(ValueError, format, -1e-100, format_spec)
606
Eric Smithc4ab8332009-11-29 17:40:57 +0000607 # issue 3382: 'f' and 'F' with inf's and nan's
608 self.assertEqual('{0:f}'.format(INF), 'inf')
609 self.assertEqual('{0:F}'.format(INF), 'INF')
610 self.assertEqual('{0:f}'.format(-INF), '-inf')
611 self.assertEqual('{0:F}'.format(-INF), '-INF')
612 self.assertEqual('{0:f}'.format(NAN), 'nan')
613 self.assertEqual('{0:F}'.format(NAN), 'NAN')
614
Benjamin Peterson0df5a852010-07-02 23:05:27 +0000615 @requires_IEEE_754
Mark Dickinson61a0d052009-04-29 21:57:15 +0000616 def test_format_testfile(self):
Brian Curtinee139682010-10-31 00:08:27 +0000617 with open(format_testfile) as testfile:
618 for line in open(format_testfile):
619 if line.startswith('--'):
620 continue
621 line = line.strip()
622 if not line:
623 continue
Mark Dickinson61a0d052009-04-29 21:57:15 +0000624
Brian Curtinee139682010-10-31 00:08:27 +0000625 lhs, rhs = map(str.strip, line.split('->'))
626 fmt, arg = lhs.split()
627 arg = float(arg)
628 self.assertEqual(fmt % arg, rhs)
629 if not math.isnan(arg) and copysign(1.0, arg) > 0.0:
630 self.assertEqual(fmt % -arg, '-' + rhs)
Mark Dickinson61a0d052009-04-29 21:57:15 +0000631
Mark Dickinson92fcc9c2009-04-29 20:41:00 +0000632 def test_issue5864(self):
Ezio Melotti2623a372010-11-21 13:34:58 +0000633 self.assertEqual(format(123.456, '.4'), '123.5')
634 self.assertEqual(format(1234.56, '.4'), '1.235e+03')
635 self.assertEqual(format(12345.6, '.4'), '1.235e+04')
Mark Dickinson92fcc9c2009-04-29 20:41:00 +0000636
Christian Heimes284d9272007-12-10 22:28:56 +0000637class ReprTestCase(unittest.TestCase):
638 def test_repr(self):
639 floats_file = open(os.path.join(os.path.split(__file__)[0],
640 'floating_points.txt'))
641 for line in floats_file:
642 line = line.strip()
643 if not line or line.startswith('#'):
644 continue
645 v = eval(line)
646 self.assertEqual(v, eval(repr(v)))
647 floats_file.close()
648
Mark Dickinson3194d142010-01-08 16:53:56 +0000649 @unittest.skipUnless(getattr(sys, 'float_repr_style', '') == 'short',
650 "applies only when using short float repr style")
651 def test_short_repr(self):
652 # test short float repr introduced in Python 3.1. One aspect
653 # of this repr is that we get some degree of str -> float ->
654 # str roundtripping. In particular, for any numeric string
655 # containing 15 or fewer significant digits, those exact same
656 # digits (modulo trailing zeros) should appear in the output.
657 # No more repr(0.03) -> "0.029999999999999999"!
658
659 test_strings = [
660 # output always includes *either* a decimal point and at
661 # least one digit after that point, or an exponent.
662 '0.0',
663 '1.0',
664 '0.01',
665 '0.02',
666 '0.03',
667 '0.04',
668 '0.05',
669 '1.23456789',
670 '10.0',
671 '100.0',
672 # values >= 1e16 get an exponent...
673 '1000000000000000.0',
674 '9999999999999990.0',
675 '1e+16',
676 '1e+17',
677 # ... and so do values < 1e-4
678 '0.001',
679 '0.001001',
680 '0.00010000000000001',
681 '0.0001',
682 '9.999999999999e-05',
683 '1e-05',
684 # values designed to provoke failure if the FPU rounding
685 # precision isn't set correctly
686 '8.72293771110361e+25',
687 '7.47005307342313e+26',
688 '2.86438000439698e+28',
689 '8.89142905246179e+28',
690 '3.08578087079232e+35',
691 ]
692
693 for s in test_strings:
694 negs = '-'+s
695 self.assertEqual(s, repr(float(s)))
696 self.assertEqual(negs, repr(float(negs)))
697
Benjamin Peterson0df5a852010-07-02 23:05:27 +0000698
699@requires_IEEE_754
Mark Dickinsonbd15a062009-11-18 19:33:35 +0000700class RoundTestCase(unittest.TestCase):
701 def test_second_argument_type(self):
702 # any type with an __index__ method should be permitted as
703 # a second argument
704 self.assertAlmostEqual(round(12.34, True), 12.3)
705
706 class MyIndex(object):
707 def __index__(self): return 4
708 self.assertAlmostEqual(round(-0.123456, MyIndex()), -0.1235)
709 # but floats should be illegal
710 self.assertRaises(TypeError, round, 3.14159, 2.0)
711
712 def test_inf_nan(self):
713 # rounding an infinity or nan returns the same number;
714 # (in py3k, rounding an infinity or nan raises an error,
715 # since the result can't be represented as a long).
716 self.assertEqual(round(INF), INF)
717 self.assertEqual(round(-INF), -INF)
718 self.assertTrue(math.isnan(round(NAN)))
719 for n in range(-5, 5):
720 self.assertEqual(round(INF, n), INF)
721 self.assertEqual(round(-INF, n), -INF)
722 self.assertTrue(math.isnan(round(NAN, n)))
723
Mark Dickinsonbce78372009-11-24 10:54:58 +0000724 self.assertRaises(TypeError, round, INF, 0.0)
725 self.assertRaises(TypeError, round, -INF, 1.0)
726 self.assertRaises(TypeError, round, NAN, "ceci n'est pas un integer")
727 self.assertRaises(TypeError, round, -0.0, 1j)
728
Mark Dickinsonbd15a062009-11-18 19:33:35 +0000729 def test_large_n(self):
730 for n in [324, 325, 400, 2**31-1, 2**31, 2**32, 2**100]:
731 self.assertEqual(round(123.456, n), 123.456)
732 self.assertEqual(round(-123.456, n), -123.456)
733 self.assertEqual(round(1e300, n), 1e300)
734 self.assertEqual(round(1e-320, n), 1e-320)
735 self.assertEqual(round(1e150, 300), 1e150)
736 self.assertEqual(round(1e300, 307), 1e300)
737 self.assertEqual(round(-3.1415, 308), -3.1415)
738 self.assertEqual(round(1e150, 309), 1e150)
739 self.assertEqual(round(1.4e-315, 315), 1e-315)
740
741 def test_small_n(self):
742 for n in [-308, -309, -400, 1-2**31, -2**31, -2**31-1, -2**100]:
743 self.assertEqual(round(123.456, n), 0.0)
744 self.assertEqual(round(-123.456, n), -0.0)
745 self.assertEqual(round(1e300, n), 0.0)
746 self.assertEqual(round(1e-320, n), 0.0)
747
748 def test_overflow(self):
749 self.assertRaises(OverflowError, round, 1.6e308, -308)
750 self.assertRaises(OverflowError, round, -1.7e308, -308)
751
752 @unittest.skipUnless(getattr(sys, 'float_repr_style', '') == 'short',
753 "test applies only when using short float repr style")
754 def test_previous_round_bugs(self):
755 # particular cases that have occurred in bug reports
756 self.assertEqual(round(562949953421312.5, 1),
757 562949953421312.5)
758 self.assertEqual(round(56294995342131.5, 3),
759 56294995342131.5)
760
761 @unittest.skipUnless(getattr(sys, 'float_repr_style', '') == 'short',
762 "test applies only when using short float repr style")
763 def test_halfway_cases(self):
764 # Halfway cases need special attention, since the current
765 # implementation has to deal with them specially. Note that
766 # 2.x rounds halfway values up (i.e., away from zero) while
767 # 3.x does round-half-to-even.
768 self.assertAlmostEqual(round(0.125, 2), 0.13)
769 self.assertAlmostEqual(round(0.375, 2), 0.38)
770 self.assertAlmostEqual(round(0.625, 2), 0.63)
771 self.assertAlmostEqual(round(0.875, 2), 0.88)
772 self.assertAlmostEqual(round(-0.125, 2), -0.13)
773 self.assertAlmostEqual(round(-0.375, 2), -0.38)
774 self.assertAlmostEqual(round(-0.625, 2), -0.63)
775 self.assertAlmostEqual(round(-0.875, 2), -0.88)
776
777 self.assertAlmostEqual(round(0.25, 1), 0.3)
778 self.assertAlmostEqual(round(0.75, 1), 0.8)
779 self.assertAlmostEqual(round(-0.25, 1), -0.3)
780 self.assertAlmostEqual(round(-0.75, 1), -0.8)
781
782 self.assertEqual(round(-6.5, 0), -7.0)
783 self.assertEqual(round(-5.5, 0), -6.0)
784 self.assertEqual(round(-1.5, 0), -2.0)
785 self.assertEqual(round(-0.5, 0), -1.0)
786 self.assertEqual(round(0.5, 0), 1.0)
787 self.assertEqual(round(1.5, 0), 2.0)
788 self.assertEqual(round(2.5, 0), 3.0)
789 self.assertEqual(round(3.5, 0), 4.0)
790 self.assertEqual(round(4.5, 0), 5.0)
791 self.assertEqual(round(5.5, 0), 6.0)
792 self.assertEqual(round(6.5, 0), 7.0)
793
794 # same but without an explicit second argument; in 3.x these
795 # will give integers
796 self.assertEqual(round(-6.5), -7.0)
797 self.assertEqual(round(-5.5), -6.0)
798 self.assertEqual(round(-1.5), -2.0)
799 self.assertEqual(round(-0.5), -1.0)
800 self.assertEqual(round(0.5), 1.0)
801 self.assertEqual(round(1.5), 2.0)
802 self.assertEqual(round(2.5), 3.0)
803 self.assertEqual(round(3.5), 4.0)
804 self.assertEqual(round(4.5), 5.0)
805 self.assertEqual(round(5.5), 6.0)
806 self.assertEqual(round(6.5), 7.0)
807
808 self.assertEqual(round(-25.0, -1), -30.0)
809 self.assertEqual(round(-15.0, -1), -20.0)
810 self.assertEqual(round(-5.0, -1), -10.0)
811 self.assertEqual(round(5.0, -1), 10.0)
812 self.assertEqual(round(15.0, -1), 20.0)
813 self.assertEqual(round(25.0, -1), 30.0)
814 self.assertEqual(round(35.0, -1), 40.0)
815 self.assertEqual(round(45.0, -1), 50.0)
816 self.assertEqual(round(55.0, -1), 60.0)
817 self.assertEqual(round(65.0, -1), 70.0)
818 self.assertEqual(round(75.0, -1), 80.0)
819 self.assertEqual(round(85.0, -1), 90.0)
820 self.assertEqual(round(95.0, -1), 100.0)
821 self.assertEqual(round(12325.0, -1), 12330.0)
822
823 self.assertEqual(round(350.0, -2), 400.0)
824 self.assertEqual(round(450.0, -2), 500.0)
825
826 self.assertAlmostEqual(round(0.5e21, -21), 1e21)
827 self.assertAlmostEqual(round(1.5e21, -21), 2e21)
828 self.assertAlmostEqual(round(2.5e21, -21), 3e21)
829 self.assertAlmostEqual(round(5.5e21, -21), 6e21)
830 self.assertAlmostEqual(round(8.5e21, -21), 9e21)
831
832 self.assertAlmostEqual(round(-1.5e22, -22), -2e22)
833 self.assertAlmostEqual(round(-0.5e22, -22), -1e22)
834 self.assertAlmostEqual(round(0.5e22, -22), 1e22)
835 self.assertAlmostEqual(round(1.5e22, -22), 2e22)
836
Benjamin Peterson0df5a852010-07-02 23:05:27 +0000837
838 @requires_IEEE_754
Eric Smithf2bf0d22009-12-02 17:43:06 +0000839 def test_format_specials(self):
840 # Test formatting of nans and infs.
841
842 def test(fmt, value, expected):
843 # Test with both % and format().
844 self.assertEqual(fmt % value, expected, fmt)
845 if not '#' in fmt:
846 # Until issue 7094 is implemented, format() for floats doesn't
847 # support '#' formatting
848 fmt = fmt[1:] # strip off the %
849 self.assertEqual(format(value, fmt), expected, fmt)
850
851 for fmt in ['%e', '%f', '%g', '%.0e', '%.6f', '%.20g',
852 '%#e', '%#f', '%#g', '%#.20e', '%#.15f', '%#.3g']:
853 pfmt = '%+' + fmt[1:]
854 sfmt = '% ' + fmt[1:]
855 test(fmt, INF, 'inf')
856 test(fmt, -INF, '-inf')
857 test(fmt, NAN, 'nan')
858 test(fmt, -NAN, 'nan')
859 # When asking for a sign, it's always provided. nans are
860 # always positive.
861 test(pfmt, INF, '+inf')
862 test(pfmt, -INF, '-inf')
863 test(pfmt, NAN, '+nan')
864 test(pfmt, -NAN, '+nan')
865 # When using ' ' for a sign code, only infs can be negative.
866 # Others have a space.
867 test(sfmt, INF, ' inf')
868 test(sfmt, -INF, '-inf')
869 test(sfmt, NAN, ' nan')
870 test(sfmt, -NAN, ' nan')
871
Mark Dickinsonbd15a062009-11-18 19:33:35 +0000872
Christian Heimes0a8143f2007-12-18 23:22:54 +0000873# Beginning with Python 2.6 float has cross platform compatible
Mark Dickinsonbf9f4d82008-07-05 11:33:52 +0000874# ways to create and represent inf and nan
Christian Heimes0a8143f2007-12-18 23:22:54 +0000875class InfNanTest(unittest.TestCase):
876 def test_inf_from_str(self):
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000877 self.assertTrue(isinf(float("inf")))
878 self.assertTrue(isinf(float("+inf")))
879 self.assertTrue(isinf(float("-inf")))
880 self.assertTrue(isinf(float("infinity")))
881 self.assertTrue(isinf(float("+infinity")))
882 self.assertTrue(isinf(float("-infinity")))
Christian Heimes0a8143f2007-12-18 23:22:54 +0000883
884 self.assertEqual(repr(float("inf")), "inf")
885 self.assertEqual(repr(float("+inf")), "inf")
886 self.assertEqual(repr(float("-inf")), "-inf")
Mark Dickinsonbf9f4d82008-07-05 11:33:52 +0000887 self.assertEqual(repr(float("infinity")), "inf")
888 self.assertEqual(repr(float("+infinity")), "inf")
889 self.assertEqual(repr(float("-infinity")), "-inf")
Christian Heimes0a8143f2007-12-18 23:22:54 +0000890
891 self.assertEqual(repr(float("INF")), "inf")
892 self.assertEqual(repr(float("+Inf")), "inf")
893 self.assertEqual(repr(float("-iNF")), "-inf")
Mark Dickinsonbf9f4d82008-07-05 11:33:52 +0000894 self.assertEqual(repr(float("Infinity")), "inf")
895 self.assertEqual(repr(float("+iNfInItY")), "inf")
896 self.assertEqual(repr(float("-INFINITY")), "-inf")
Christian Heimes0a8143f2007-12-18 23:22:54 +0000897
898 self.assertEqual(str(float("inf")), "inf")
899 self.assertEqual(str(float("+inf")), "inf")
900 self.assertEqual(str(float("-inf")), "-inf")
Mark Dickinsonbf9f4d82008-07-05 11:33:52 +0000901 self.assertEqual(str(float("infinity")), "inf")
902 self.assertEqual(str(float("+infinity")), "inf")
903 self.assertEqual(str(float("-infinity")), "-inf")
Christian Heimes0a8143f2007-12-18 23:22:54 +0000904
905 self.assertRaises(ValueError, float, "info")
906 self.assertRaises(ValueError, float, "+info")
907 self.assertRaises(ValueError, float, "-info")
908 self.assertRaises(ValueError, float, "in")
909 self.assertRaises(ValueError, float, "+in")
910 self.assertRaises(ValueError, float, "-in")
Mark Dickinsonbf9f4d82008-07-05 11:33:52 +0000911 self.assertRaises(ValueError, float, "infinit")
912 self.assertRaises(ValueError, float, "+Infin")
913 self.assertRaises(ValueError, float, "-INFI")
914 self.assertRaises(ValueError, float, "infinitys")
Christian Heimes0a8143f2007-12-18 23:22:54 +0000915
916 def test_inf_as_str(self):
917 self.assertEqual(repr(1e300 * 1e300), "inf")
918 self.assertEqual(repr(-1e300 * 1e300), "-inf")
919
920 self.assertEqual(str(1e300 * 1e300), "inf")
921 self.assertEqual(str(-1e300 * 1e300), "-inf")
922
923 def test_nan_from_str(self):
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000924 self.assertTrue(isnan(float("nan")))
925 self.assertTrue(isnan(float("+nan")))
926 self.assertTrue(isnan(float("-nan")))
Christian Heimes0a8143f2007-12-18 23:22:54 +0000927
928 self.assertEqual(repr(float("nan")), "nan")
929 self.assertEqual(repr(float("+nan")), "nan")
930 self.assertEqual(repr(float("-nan")), "nan")
931
932 self.assertEqual(repr(float("NAN")), "nan")
933 self.assertEqual(repr(float("+NAn")), "nan")
934 self.assertEqual(repr(float("-NaN")), "nan")
935
936 self.assertEqual(str(float("nan")), "nan")
937 self.assertEqual(str(float("+nan")), "nan")
938 self.assertEqual(str(float("-nan")), "nan")
939
940 self.assertRaises(ValueError, float, "nana")
941 self.assertRaises(ValueError, float, "+nana")
942 self.assertRaises(ValueError, float, "-nana")
943 self.assertRaises(ValueError, float, "na")
944 self.assertRaises(ValueError, float, "+na")
945 self.assertRaises(ValueError, float, "-na")
946
947 def test_nan_as_str(self):
948 self.assertEqual(repr(1e300 * 1e300 * 0), "nan")
949 self.assertEqual(repr(-1e300 * 1e300 * 0), "nan")
950
951 self.assertEqual(str(1e300 * 1e300 * 0), "nan")
952 self.assertEqual(str(-1e300 * 1e300 * 0), "nan")
Christian Heimes284d9272007-12-10 22:28:56 +0000953
Christian Heimes6f341092008-04-18 23:13:07 +0000954 def notest_float_nan(self):
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000955 self.assertTrue(NAN.is_nan())
956 self.assertFalse(INF.is_nan())
957 self.assertFalse((0.).is_nan())
Christian Heimes6f341092008-04-18 23:13:07 +0000958
959 def notest_float_inf(self):
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000960 self.assertTrue(INF.is_inf())
961 self.assertFalse(NAN.is_inf())
962 self.assertFalse((0.).is_inf())
Christian Heimes6f341092008-04-18 23:13:07 +0000963
Mark Dickinson5e0c2742010-04-05 18:07:51 +0000964 def test_hash_inf(self):
965 # the actual values here should be regarded as an
966 # implementation detail, but they need to be
967 # identical to those used in the Decimal module.
968 self.assertEqual(hash(float('inf')), 314159)
969 self.assertEqual(hash(float('-inf')), -271828)
970 self.assertEqual(hash(float('nan')), 0)
971
972
Mark Dickinson7103aa42008-07-15 19:08:33 +0000973fromHex = float.fromhex
974toHex = float.hex
975class HexFloatTestCase(unittest.TestCase):
976 MAX = fromHex('0x.fffffffffffff8p+1024') # max normal
977 MIN = fromHex('0x1p-1022') # min normal
978 TINY = fromHex('0x0.0000000000001p-1022') # min subnormal
979 EPS = fromHex('0x0.0000000000001p0') # diff between 1.0 and next float up
980
981 def identical(self, x, y):
982 # check that floats x and y are identical, or that both
983 # are NaNs
984 if isnan(x) or isnan(y):
985 if isnan(x) == isnan(y):
986 return
987 elif x == y and (x != 0.0 or copysign(1.0, x) == copysign(1.0, y)):
988 return
989 self.fail('%r not identical to %r' % (x, y))
990
991 def test_ends(self):
Mark Dickinson62764562008-07-15 21:55:23 +0000992 self.identical(self.MIN, ldexp(1.0, -1022))
993 self.identical(self.TINY, ldexp(1.0, -1074))
994 self.identical(self.EPS, ldexp(1.0, -52))
995 self.identical(self.MAX, 2.*(ldexp(1.0, 1023) - ldexp(1.0, 970)))
Mark Dickinson7103aa42008-07-15 19:08:33 +0000996
997 def test_invalid_inputs(self):
998 invalid_inputs = [
999 'infi', # misspelt infinities and nans
1000 '-Infinit',
1001 '++inf',
1002 '-+Inf',
1003 '--nan',
1004 '+-NaN',
1005 'snan',
1006 'NaNs',
1007 'nna',
Mark Dickinsonb1d45852009-05-11 15:33:08 +00001008 'an',
1009 'nf',
1010 'nfinity',
1011 'inity',
1012 'iinity',
Mark Dickinson7103aa42008-07-15 19:08:33 +00001013 '0xnan',
1014 '',
1015 ' ',
1016 'x1.0p0',
1017 '0xX1.0p0',
1018 '+ 0x1.0p0', # internal whitespace
1019 '- 0x1.0p0',
1020 '0 x1.0p0',
1021 '0x 1.0p0',
1022 '0x1 2.0p0',
1023 '+0x1 .0p0',
1024 '0x1. 0p0',
1025 '-0x1.0 1p0',
1026 '-0x1.0 p0',
1027 '+0x1.0p +0',
1028 '0x1.0p -0',
1029 '0x1.0p 0',
1030 '+0x1.0p+ 0',
1031 '-0x1.0p- 0',
1032 '++0x1.0p-0', # double signs
1033 '--0x1.0p0',
1034 '+-0x1.0p+0',
1035 '-+0x1.0p0',
1036 '0x1.0p++0',
1037 '+0x1.0p+-0',
1038 '-0x1.0p-+0',
1039 '0x1.0p--0',
1040 '0x1.0.p0',
1041 '0x.p0', # no hex digits before or after point
1042 '0x1,p0', # wrong decimal point character
1043 '0x1pa',
1044 u'0x1p\uff10', # fullwidth Unicode digits
1045 u'\uff10x1p0',
1046 u'0x\uff11p0',
1047 u'0x1.\uff10p0',
1048 '0x1p0 \n 0x2p0',
1049 '0x1p0\0 0x1p0', # embedded null byte is not end of string
1050 ]
1051 for x in invalid_inputs:
Mark Dickinson892429b2008-08-21 20:02:24 +00001052 try:
1053 result = fromHex(x)
1054 except ValueError:
1055 pass
1056 else:
1057 self.fail('Expected float.fromhex(%r) to raise ValueError; '
1058 'got %r instead' % (x, result))
Mark Dickinson7103aa42008-07-15 19:08:33 +00001059
1060
Mark Dickinsonb1d45852009-05-11 15:33:08 +00001061 def test_whitespace(self):
1062 value_pairs = [
1063 ('inf', INF),
1064 ('-Infinity', -INF),
1065 ('nan', NAN),
1066 ('1.0', 1.0),
1067 ('-0x.2', -0.125),
1068 ('-0.0', -0.0)
1069 ]
1070 whitespace = [
1071 '',
1072 ' ',
1073 '\t',
1074 '\n',
1075 '\n \t',
1076 '\f',
1077 '\v',
1078 '\r'
1079 ]
1080 for inp, expected in value_pairs:
1081 for lead in whitespace:
1082 for trail in whitespace:
1083 got = fromHex(lead + inp + trail)
1084 self.identical(got, expected)
1085
1086
Mark Dickinson7103aa42008-07-15 19:08:33 +00001087 def test_from_hex(self):
1088 MIN = self.MIN;
1089 MAX = self.MAX;
1090 TINY = self.TINY;
1091 EPS = self.EPS;
1092
1093 # two spellings of infinity, with optional signs; case-insensitive
1094 self.identical(fromHex('inf'), INF)
1095 self.identical(fromHex('+Inf'), INF)
1096 self.identical(fromHex('-INF'), -INF)
1097 self.identical(fromHex('iNf'), INF)
1098 self.identical(fromHex('Infinity'), INF)
1099 self.identical(fromHex('+INFINITY'), INF)
1100 self.identical(fromHex('-infinity'), -INF)
1101 self.identical(fromHex('-iNFiNitY'), -INF)
1102
1103 # nans with optional sign; case insensitive
1104 self.identical(fromHex('nan'), NAN)
1105 self.identical(fromHex('+NaN'), NAN)
1106 self.identical(fromHex('-NaN'), NAN)
1107 self.identical(fromHex('-nAN'), NAN)
1108
1109 # variations in input format
1110 self.identical(fromHex('1'), 1.0)
1111 self.identical(fromHex('+1'), 1.0)
1112 self.identical(fromHex('1.'), 1.0)
1113 self.identical(fromHex('1.0'), 1.0)
1114 self.identical(fromHex('1.0p0'), 1.0)
1115 self.identical(fromHex('01'), 1.0)
1116 self.identical(fromHex('01.'), 1.0)
1117 self.identical(fromHex('0x1'), 1.0)
1118 self.identical(fromHex('0x1.'), 1.0)
1119 self.identical(fromHex('0x1.0'), 1.0)
1120 self.identical(fromHex('+0x1.0'), 1.0)
1121 self.identical(fromHex('0x1p0'), 1.0)
1122 self.identical(fromHex('0X1p0'), 1.0)
1123 self.identical(fromHex('0X1P0'), 1.0)
1124 self.identical(fromHex('0x1P0'), 1.0)
1125 self.identical(fromHex('0x1.p0'), 1.0)
1126 self.identical(fromHex('0x1.0p0'), 1.0)
1127 self.identical(fromHex('0x.1p4'), 1.0)
1128 self.identical(fromHex('0x.1p04'), 1.0)
1129 self.identical(fromHex('0x.1p004'), 1.0)
1130 self.identical(fromHex('0x1p+0'), 1.0)
1131 self.identical(fromHex('0x1P-0'), 1.0)
1132 self.identical(fromHex('+0x1p0'), 1.0)
1133 self.identical(fromHex('0x01p0'), 1.0)
1134 self.identical(fromHex('0x1p00'), 1.0)
1135 self.identical(fromHex(u'0x1p0'), 1.0)
1136 self.identical(fromHex(' 0x1p0 '), 1.0)
1137 self.identical(fromHex('\n 0x1p0'), 1.0)
1138 self.identical(fromHex('0x1p0 \t'), 1.0)
1139 self.identical(fromHex('0xap0'), 10.0)
1140 self.identical(fromHex('0xAp0'), 10.0)
1141 self.identical(fromHex('0xaP0'), 10.0)
1142 self.identical(fromHex('0xAP0'), 10.0)
1143 self.identical(fromHex('0xbep0'), 190.0)
1144 self.identical(fromHex('0xBep0'), 190.0)
1145 self.identical(fromHex('0xbEp0'), 190.0)
1146 self.identical(fromHex('0XBE0P-4'), 190.0)
1147 self.identical(fromHex('0xBEp0'), 190.0)
1148 self.identical(fromHex('0xB.Ep4'), 190.0)
1149 self.identical(fromHex('0x.BEp8'), 190.0)
1150 self.identical(fromHex('0x.0BEp12'), 190.0)
1151
1152 # moving the point around
1153 pi = fromHex('0x1.921fb54442d18p1')
1154 self.identical(fromHex('0x.006487ed5110b46p11'), pi)
1155 self.identical(fromHex('0x.00c90fdaa22168cp10'), pi)
1156 self.identical(fromHex('0x.01921fb54442d18p9'), pi)
1157 self.identical(fromHex('0x.03243f6a8885a3p8'), pi)
1158 self.identical(fromHex('0x.06487ed5110b46p7'), pi)
1159 self.identical(fromHex('0x.0c90fdaa22168cp6'), pi)
1160 self.identical(fromHex('0x.1921fb54442d18p5'), pi)
1161 self.identical(fromHex('0x.3243f6a8885a3p4'), pi)
1162 self.identical(fromHex('0x.6487ed5110b46p3'), pi)
1163 self.identical(fromHex('0x.c90fdaa22168cp2'), pi)
1164 self.identical(fromHex('0x1.921fb54442d18p1'), pi)
1165 self.identical(fromHex('0x3.243f6a8885a3p0'), pi)
1166 self.identical(fromHex('0x6.487ed5110b46p-1'), pi)
1167 self.identical(fromHex('0xc.90fdaa22168cp-2'), pi)
1168 self.identical(fromHex('0x19.21fb54442d18p-3'), pi)
1169 self.identical(fromHex('0x32.43f6a8885a3p-4'), pi)
1170 self.identical(fromHex('0x64.87ed5110b46p-5'), pi)
1171 self.identical(fromHex('0xc9.0fdaa22168cp-6'), pi)
1172 self.identical(fromHex('0x192.1fb54442d18p-7'), pi)
1173 self.identical(fromHex('0x324.3f6a8885a3p-8'), pi)
1174 self.identical(fromHex('0x648.7ed5110b46p-9'), pi)
1175 self.identical(fromHex('0xc90.fdaa22168cp-10'), pi)
1176 self.identical(fromHex('0x1921.fb54442d18p-11'), pi)
1177 # ...
1178 self.identical(fromHex('0x1921fb54442d1.8p-47'), pi)
1179 self.identical(fromHex('0x3243f6a8885a3p-48'), pi)
1180 self.identical(fromHex('0x6487ed5110b46p-49'), pi)
1181 self.identical(fromHex('0xc90fdaa22168cp-50'), pi)
1182 self.identical(fromHex('0x1921fb54442d18p-51'), pi)
1183 self.identical(fromHex('0x3243f6a8885a30p-52'), pi)
1184 self.identical(fromHex('0x6487ed5110b460p-53'), pi)
1185 self.identical(fromHex('0xc90fdaa22168c0p-54'), pi)
1186 self.identical(fromHex('0x1921fb54442d180p-55'), pi)
1187
1188
1189 # results that should overflow...
1190 self.assertRaises(OverflowError, fromHex, '-0x1p1024')
1191 self.assertRaises(OverflowError, fromHex, '0x1p+1025')
1192 self.assertRaises(OverflowError, fromHex, '+0X1p1030')
1193 self.assertRaises(OverflowError, fromHex, '-0x1p+1100')
1194 self.assertRaises(OverflowError, fromHex, '0X1p123456789123456789')
1195 self.assertRaises(OverflowError, fromHex, '+0X.8p+1025')
1196 self.assertRaises(OverflowError, fromHex, '+0x0.8p1025')
1197 self.assertRaises(OverflowError, fromHex, '-0x0.4p1026')
1198 self.assertRaises(OverflowError, fromHex, '0X2p+1023')
1199 self.assertRaises(OverflowError, fromHex, '0x2.p1023')
1200 self.assertRaises(OverflowError, fromHex, '-0x2.0p+1023')
1201 self.assertRaises(OverflowError, fromHex, '+0X4p+1022')
1202 self.assertRaises(OverflowError, fromHex, '0x1.ffffffffffffffp+1023')
1203 self.assertRaises(OverflowError, fromHex, '-0X1.fffffffffffff9p1023')
1204 self.assertRaises(OverflowError, fromHex, '0X1.fffffffffffff8p1023')
1205 self.assertRaises(OverflowError, fromHex, '+0x3.fffffffffffffp1022')
1206 self.assertRaises(OverflowError, fromHex, '0x3fffffffffffffp+970')
1207 self.assertRaises(OverflowError, fromHex, '0x10000000000000000p960')
1208 self.assertRaises(OverflowError, fromHex, '-0Xffffffffffffffffp960')
1209
1210 # ...and those that round to +-max float
1211 self.identical(fromHex('+0x1.fffffffffffffp+1023'), MAX)
1212 self.identical(fromHex('-0X1.fffffffffffff7p1023'), -MAX)
1213 self.identical(fromHex('0X1.fffffffffffff7fffffffffffffp1023'), MAX)
1214
1215 # zeros
1216 self.identical(fromHex('0x0p0'), 0.0)
1217 self.identical(fromHex('0x0p1000'), 0.0)
1218 self.identical(fromHex('-0x0p1023'), -0.0)
1219 self.identical(fromHex('0X0p1024'), 0.0)
1220 self.identical(fromHex('-0x0p1025'), -0.0)
1221 self.identical(fromHex('0X0p2000'), 0.0)
1222 self.identical(fromHex('0x0p123456789123456789'), 0.0)
1223 self.identical(fromHex('-0X0p-0'), -0.0)
1224 self.identical(fromHex('-0X0p-1000'), -0.0)
1225 self.identical(fromHex('0x0p-1023'), 0.0)
1226 self.identical(fromHex('-0X0p-1024'), -0.0)
1227 self.identical(fromHex('-0x0p-1025'), -0.0)
1228 self.identical(fromHex('-0x0p-1072'), -0.0)
1229 self.identical(fromHex('0X0p-1073'), 0.0)
1230 self.identical(fromHex('-0x0p-1074'), -0.0)
1231 self.identical(fromHex('0x0p-1075'), 0.0)
1232 self.identical(fromHex('0X0p-1076'), 0.0)
1233 self.identical(fromHex('-0X0p-2000'), -0.0)
1234 self.identical(fromHex('-0x0p-123456789123456789'), -0.0)
1235
1236 # values that should underflow to 0
1237 self.identical(fromHex('0X1p-1075'), 0.0)
1238 self.identical(fromHex('-0X1p-1075'), -0.0)
1239 self.identical(fromHex('-0x1p-123456789123456789'), -0.0)
1240 self.identical(fromHex('0x1.00000000000000001p-1075'), TINY)
1241 self.identical(fromHex('-0x1.1p-1075'), -TINY)
1242 self.identical(fromHex('0x1.fffffffffffffffffp-1075'), TINY)
1243
1244 # check round-half-even is working correctly near 0 ...
1245 self.identical(fromHex('0x1p-1076'), 0.0)
1246 self.identical(fromHex('0X2p-1076'), 0.0)
1247 self.identical(fromHex('0X3p-1076'), TINY)
1248 self.identical(fromHex('0x4p-1076'), TINY)
1249 self.identical(fromHex('0X5p-1076'), TINY)
1250 self.identical(fromHex('0X6p-1076'), 2*TINY)
1251 self.identical(fromHex('0x7p-1076'), 2*TINY)
1252 self.identical(fromHex('0X8p-1076'), 2*TINY)
1253 self.identical(fromHex('0X9p-1076'), 2*TINY)
1254 self.identical(fromHex('0xap-1076'), 2*TINY)
1255 self.identical(fromHex('0Xbp-1076'), 3*TINY)
1256 self.identical(fromHex('0xcp-1076'), 3*TINY)
1257 self.identical(fromHex('0Xdp-1076'), 3*TINY)
1258 self.identical(fromHex('0Xep-1076'), 4*TINY)
1259 self.identical(fromHex('0xfp-1076'), 4*TINY)
1260 self.identical(fromHex('0x10p-1076'), 4*TINY)
1261 self.identical(fromHex('-0x1p-1076'), -0.0)
1262 self.identical(fromHex('-0X2p-1076'), -0.0)
1263 self.identical(fromHex('-0x3p-1076'), -TINY)
1264 self.identical(fromHex('-0X4p-1076'), -TINY)
1265 self.identical(fromHex('-0x5p-1076'), -TINY)
1266 self.identical(fromHex('-0x6p-1076'), -2*TINY)
1267 self.identical(fromHex('-0X7p-1076'), -2*TINY)
1268 self.identical(fromHex('-0X8p-1076'), -2*TINY)
1269 self.identical(fromHex('-0X9p-1076'), -2*TINY)
1270 self.identical(fromHex('-0Xap-1076'), -2*TINY)
1271 self.identical(fromHex('-0xbp-1076'), -3*TINY)
1272 self.identical(fromHex('-0xcp-1076'), -3*TINY)
1273 self.identical(fromHex('-0Xdp-1076'), -3*TINY)
1274 self.identical(fromHex('-0xep-1076'), -4*TINY)
1275 self.identical(fromHex('-0Xfp-1076'), -4*TINY)
1276 self.identical(fromHex('-0X10p-1076'), -4*TINY)
1277
1278 # ... and near MIN ...
1279 self.identical(fromHex('0x0.ffffffffffffd6p-1022'), MIN-3*TINY)
1280 self.identical(fromHex('0x0.ffffffffffffd8p-1022'), MIN-2*TINY)
1281 self.identical(fromHex('0x0.ffffffffffffdap-1022'), MIN-2*TINY)
1282 self.identical(fromHex('0x0.ffffffffffffdcp-1022'), MIN-2*TINY)
1283 self.identical(fromHex('0x0.ffffffffffffdep-1022'), MIN-2*TINY)
1284 self.identical(fromHex('0x0.ffffffffffffe0p-1022'), MIN-2*TINY)
1285 self.identical(fromHex('0x0.ffffffffffffe2p-1022'), MIN-2*TINY)
1286 self.identical(fromHex('0x0.ffffffffffffe4p-1022'), MIN-2*TINY)
1287 self.identical(fromHex('0x0.ffffffffffffe6p-1022'), MIN-2*TINY)
1288 self.identical(fromHex('0x0.ffffffffffffe8p-1022'), MIN-2*TINY)
1289 self.identical(fromHex('0x0.ffffffffffffeap-1022'), MIN-TINY)
1290 self.identical(fromHex('0x0.ffffffffffffecp-1022'), MIN-TINY)
1291 self.identical(fromHex('0x0.ffffffffffffeep-1022'), MIN-TINY)
1292 self.identical(fromHex('0x0.fffffffffffff0p-1022'), MIN-TINY)
1293 self.identical(fromHex('0x0.fffffffffffff2p-1022'), MIN-TINY)
1294 self.identical(fromHex('0x0.fffffffffffff4p-1022'), MIN-TINY)
1295 self.identical(fromHex('0x0.fffffffffffff6p-1022'), MIN-TINY)
1296 self.identical(fromHex('0x0.fffffffffffff8p-1022'), MIN)
1297 self.identical(fromHex('0x0.fffffffffffffap-1022'), MIN)
1298 self.identical(fromHex('0x0.fffffffffffffcp-1022'), MIN)
1299 self.identical(fromHex('0x0.fffffffffffffep-1022'), MIN)
1300 self.identical(fromHex('0x1.00000000000000p-1022'), MIN)
1301 self.identical(fromHex('0x1.00000000000002p-1022'), MIN)
1302 self.identical(fromHex('0x1.00000000000004p-1022'), MIN)
1303 self.identical(fromHex('0x1.00000000000006p-1022'), MIN)
1304 self.identical(fromHex('0x1.00000000000008p-1022'), MIN)
1305 self.identical(fromHex('0x1.0000000000000ap-1022'), MIN+TINY)
1306 self.identical(fromHex('0x1.0000000000000cp-1022'), MIN+TINY)
1307 self.identical(fromHex('0x1.0000000000000ep-1022'), MIN+TINY)
1308 self.identical(fromHex('0x1.00000000000010p-1022'), MIN+TINY)
1309 self.identical(fromHex('0x1.00000000000012p-1022'), MIN+TINY)
1310 self.identical(fromHex('0x1.00000000000014p-1022'), MIN+TINY)
1311 self.identical(fromHex('0x1.00000000000016p-1022'), MIN+TINY)
1312 self.identical(fromHex('0x1.00000000000018p-1022'), MIN+2*TINY)
1313
1314 # ... and near 1.0.
1315 self.identical(fromHex('0x0.fffffffffffff0p0'), 1.0-EPS)
1316 self.identical(fromHex('0x0.fffffffffffff1p0'), 1.0-EPS)
1317 self.identical(fromHex('0X0.fffffffffffff2p0'), 1.0-EPS)
1318 self.identical(fromHex('0x0.fffffffffffff3p0'), 1.0-EPS)
1319 self.identical(fromHex('0X0.fffffffffffff4p0'), 1.0-EPS)
1320 self.identical(fromHex('0X0.fffffffffffff5p0'), 1.0-EPS/2)
1321 self.identical(fromHex('0X0.fffffffffffff6p0'), 1.0-EPS/2)
1322 self.identical(fromHex('0x0.fffffffffffff7p0'), 1.0-EPS/2)
1323 self.identical(fromHex('0x0.fffffffffffff8p0'), 1.0-EPS/2)
1324 self.identical(fromHex('0X0.fffffffffffff9p0'), 1.0-EPS/2)
1325 self.identical(fromHex('0X0.fffffffffffffap0'), 1.0-EPS/2)
1326 self.identical(fromHex('0x0.fffffffffffffbp0'), 1.0-EPS/2)
1327 self.identical(fromHex('0X0.fffffffffffffcp0'), 1.0)
1328 self.identical(fromHex('0x0.fffffffffffffdp0'), 1.0)
1329 self.identical(fromHex('0X0.fffffffffffffep0'), 1.0)
1330 self.identical(fromHex('0x0.ffffffffffffffp0'), 1.0)
1331 self.identical(fromHex('0X1.00000000000000p0'), 1.0)
1332 self.identical(fromHex('0X1.00000000000001p0'), 1.0)
1333 self.identical(fromHex('0x1.00000000000002p0'), 1.0)
1334 self.identical(fromHex('0X1.00000000000003p0'), 1.0)
1335 self.identical(fromHex('0x1.00000000000004p0'), 1.0)
1336 self.identical(fromHex('0X1.00000000000005p0'), 1.0)
1337 self.identical(fromHex('0X1.00000000000006p0'), 1.0)
1338 self.identical(fromHex('0X1.00000000000007p0'), 1.0)
1339 self.identical(fromHex('0x1.00000000000007ffffffffffffffffffffp0'),
1340 1.0)
1341 self.identical(fromHex('0x1.00000000000008p0'), 1.0)
1342 self.identical(fromHex('0x1.00000000000008000000000000000001p0'),
1343 1+EPS)
1344 self.identical(fromHex('0X1.00000000000009p0'), 1.0+EPS)
1345 self.identical(fromHex('0x1.0000000000000ap0'), 1.0+EPS)
1346 self.identical(fromHex('0x1.0000000000000bp0'), 1.0+EPS)
1347 self.identical(fromHex('0X1.0000000000000cp0'), 1.0+EPS)
1348 self.identical(fromHex('0x1.0000000000000dp0'), 1.0+EPS)
1349 self.identical(fromHex('0x1.0000000000000ep0'), 1.0+EPS)
1350 self.identical(fromHex('0X1.0000000000000fp0'), 1.0+EPS)
1351 self.identical(fromHex('0x1.00000000000010p0'), 1.0+EPS)
1352 self.identical(fromHex('0X1.00000000000011p0'), 1.0+EPS)
1353 self.identical(fromHex('0x1.00000000000012p0'), 1.0+EPS)
1354 self.identical(fromHex('0X1.00000000000013p0'), 1.0+EPS)
1355 self.identical(fromHex('0X1.00000000000014p0'), 1.0+EPS)
1356 self.identical(fromHex('0x1.00000000000015p0'), 1.0+EPS)
1357 self.identical(fromHex('0x1.00000000000016p0'), 1.0+EPS)
1358 self.identical(fromHex('0X1.00000000000017p0'), 1.0+EPS)
1359 self.identical(fromHex('0x1.00000000000017ffffffffffffffffffffp0'),
1360 1.0+EPS)
1361 self.identical(fromHex('0x1.00000000000018p0'), 1.0+2*EPS)
1362 self.identical(fromHex('0X1.00000000000018000000000000000001p0'),
1363 1.0+2*EPS)
1364 self.identical(fromHex('0x1.00000000000019p0'), 1.0+2*EPS)
1365 self.identical(fromHex('0X1.0000000000001ap0'), 1.0+2*EPS)
1366 self.identical(fromHex('0X1.0000000000001bp0'), 1.0+2*EPS)
1367 self.identical(fromHex('0x1.0000000000001cp0'), 1.0+2*EPS)
1368 self.identical(fromHex('0x1.0000000000001dp0'), 1.0+2*EPS)
1369 self.identical(fromHex('0x1.0000000000001ep0'), 1.0+2*EPS)
1370 self.identical(fromHex('0X1.0000000000001fp0'), 1.0+2*EPS)
1371 self.identical(fromHex('0x1.00000000000020p0'), 1.0+2*EPS)
1372
1373 def test_roundtrip(self):
1374 def roundtrip(x):
1375 return fromHex(toHex(x))
1376
1377 for x in [NAN, INF, self.MAX, self.MIN, self.MIN-self.TINY, self.TINY, 0.0]:
1378 self.identical(x, roundtrip(x))
1379 self.identical(-x, roundtrip(-x))
1380
1381 # fromHex(toHex(x)) should exactly recover x, for any non-NaN float x.
1382 import random
1383 for i in xrange(10000):
1384 e = random.randrange(-1200, 1200)
1385 m = random.random()
1386 s = random.choice([1.0, -1.0])
1387 try:
1388 x = s*ldexp(m, e)
1389 except OverflowError:
1390 pass
1391 else:
1392 self.identical(x, fromHex(toHex(x)))
1393
Christian Heimes6f341092008-04-18 23:13:07 +00001394
Michael W. Hudsonba283e22005-05-27 15:23:20 +00001395def test_main():
1396 test_support.run_unittest(
Amaury Forgeot d'Arcfeb8cad2008-09-06 20:53:51 +00001397 GeneralFloatCases,
Michael W. Hudsonba283e22005-05-27 15:23:20 +00001398 FormatFunctionsTestCase,
1399 UnknownFormatTestCase,
Christian Heimes284d9272007-12-10 22:28:56 +00001400 IEEEFormatTestCase,
Christian Heimes0a8143f2007-12-18 23:22:54 +00001401 ReprTestCase,
Mark Dickinsonbd15a062009-11-18 19:33:35 +00001402 RoundTestCase,
Christian Heimes0a8143f2007-12-18 23:22:54 +00001403 InfNanTest,
Mark Dickinson7103aa42008-07-15 19:08:33 +00001404 HexFloatTestCase,
Christian Heimesf15c66e2007-12-11 00:54:34 +00001405 )
Michael W. Hudsonba283e22005-05-27 15:23:20 +00001406
1407if __name__ == '__main__':
1408 test_main()