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