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