blob: eb119ce6f0c19558115c8a5a227ff3fa7d474757 [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
167 def test_floatasratio(self):
168 for f, ratio in [
169 (0.875, (7, 8)),
170 (-0.875, (-7, 8)),
171 (0.0, (0, 1)),
172 (11.5, (23, 2)),
173 ]:
174 self.assertEqual(f.as_integer_ratio(), ratio)
175
176 for i in range(10000):
177 f = random.random()
178 f *= 10 ** random.randint(-100, 100)
179 n, d = f.as_integer_ratio()
180 self.assertEqual(float(n).__truediv__(d), f)
181
182 R = fractions.Fraction
183 self.assertEqual(R(0, 1),
184 R(*float(0.0).as_integer_ratio()))
185 self.assertEqual(R(5, 2),
186 R(*float(2.5).as_integer_ratio()))
187 self.assertEqual(R(1, 2),
188 R(*float(0.5).as_integer_ratio()))
189 self.assertEqual(R(4728779608739021, 2251799813685248),
190 R(*float(2.1).as_integer_ratio()))
191 self.assertEqual(R(-4728779608739021, 2251799813685248),
192 R(*float(-2.1).as_integer_ratio()))
193 self.assertEqual(R(-2100, 1),
194 R(*float(-2100.0).as_integer_ratio()))
195
196 self.assertRaises(OverflowError, float('inf').as_integer_ratio)
197 self.assertRaises(OverflowError, float('-inf').as_integer_ratio)
198 self.assertRaises(ValueError, float('nan').as_integer_ratio)
199
Mark Dickinson99d652e2009-12-30 12:12:23 +0000200 def assertEqualAndEqualSign(self, a, b):
201 # fail unless a == b and a and b have the same sign bit;
202 # the only difference from assertEqual is that this test
Ezio Melottic2077b02011-03-16 12:34:31 +0200203 # distinguishes -0.0 and 0.0.
Mark Dickinson99d652e2009-12-30 12:12:23 +0000204 self.assertEqual((a, copysign(1.0, a)), (b, copysign(1.0, b)))
205
206 @requires_IEEE_754
Mark Dickinsonecf8ec62010-12-04 12:30:41 +0000207 def test_float_mod(self):
208 # Check behaviour of % operator for IEEE 754 special cases.
209 # In particular, check signs of zeros.
210 mod = operator.mod
211
212 self.assertEqualAndEqualSign(mod(-1.0, 1.0), 0.0)
213 self.assertEqualAndEqualSign(mod(-1e-100, 1.0), 1.0)
214 self.assertEqualAndEqualSign(mod(-0.0, 1.0), 0.0)
215 self.assertEqualAndEqualSign(mod(0.0, 1.0), 0.0)
216 self.assertEqualAndEqualSign(mod(1e-100, 1.0), 1e-100)
217 self.assertEqualAndEqualSign(mod(1.0, 1.0), 0.0)
218
219 self.assertEqualAndEqualSign(mod(-1.0, -1.0), -0.0)
220 self.assertEqualAndEqualSign(mod(-1e-100, -1.0), -1e-100)
221 self.assertEqualAndEqualSign(mod(-0.0, -1.0), -0.0)
222 self.assertEqualAndEqualSign(mod(0.0, -1.0), -0.0)
223 self.assertEqualAndEqualSign(mod(1e-100, -1.0), -1.0)
224 self.assertEqualAndEqualSign(mod(1.0, -1.0), -0.0)
225
226 @requires_IEEE_754
Mark Dickinson99d652e2009-12-30 12:12:23 +0000227 def test_float_pow(self):
228 # test builtin pow and ** operator for IEEE 754 special cases.
229 # Special cases taken from section F.9.4.4 of the C99 specification
230
231 for pow_op in pow, operator.pow:
232 # x**NAN is NAN for any x except 1
233 self.assertTrue(isnan(pow_op(-INF, NAN)))
234 self.assertTrue(isnan(pow_op(-2.0, NAN)))
235 self.assertTrue(isnan(pow_op(-1.0, NAN)))
236 self.assertTrue(isnan(pow_op(-0.5, NAN)))
237 self.assertTrue(isnan(pow_op(-0.0, NAN)))
238 self.assertTrue(isnan(pow_op(0.0, NAN)))
239 self.assertTrue(isnan(pow_op(0.5, NAN)))
240 self.assertTrue(isnan(pow_op(2.0, NAN)))
241 self.assertTrue(isnan(pow_op(INF, NAN)))
242 self.assertTrue(isnan(pow_op(NAN, NAN)))
243
244 # NAN**y is NAN for any y except +-0
245 self.assertTrue(isnan(pow_op(NAN, -INF)))
246 self.assertTrue(isnan(pow_op(NAN, -2.0)))
247 self.assertTrue(isnan(pow_op(NAN, -1.0)))
248 self.assertTrue(isnan(pow_op(NAN, -0.5)))
249 self.assertTrue(isnan(pow_op(NAN, 0.5)))
250 self.assertTrue(isnan(pow_op(NAN, 1.0)))
251 self.assertTrue(isnan(pow_op(NAN, 2.0)))
252 self.assertTrue(isnan(pow_op(NAN, INF)))
253
254 # (+-0)**y raises ZeroDivisionError for y a negative odd integer
255 self.assertRaises(ZeroDivisionError, pow_op, -0.0, -1.0)
256 self.assertRaises(ZeroDivisionError, pow_op, 0.0, -1.0)
257
258 # (+-0)**y raises ZeroDivisionError for y finite and negative
259 # but not an odd integer
260 self.assertRaises(ZeroDivisionError, pow_op, -0.0, -2.0)
261 self.assertRaises(ZeroDivisionError, pow_op, -0.0, -0.5)
262 self.assertRaises(ZeroDivisionError, pow_op, 0.0, -2.0)
263 self.assertRaises(ZeroDivisionError, pow_op, 0.0, -0.5)
264
265 # (+-0)**y is +-0 for y a positive odd integer
266 self.assertEqualAndEqualSign(pow_op(-0.0, 1.0), -0.0)
267 self.assertEqualAndEqualSign(pow_op(0.0, 1.0), 0.0)
268
269 # (+-0)**y is 0 for y finite and positive but not an odd integer
270 self.assertEqualAndEqualSign(pow_op(-0.0, 0.5), 0.0)
271 self.assertEqualAndEqualSign(pow_op(-0.0, 2.0), 0.0)
272 self.assertEqualAndEqualSign(pow_op(0.0, 0.5), 0.0)
273 self.assertEqualAndEqualSign(pow_op(0.0, 2.0), 0.0)
274
275 # (-1)**+-inf is 1
276 self.assertEqualAndEqualSign(pow_op(-1.0, -INF), 1.0)
277 self.assertEqualAndEqualSign(pow_op(-1.0, INF), 1.0)
278
279 # 1**y is 1 for any y, even if y is an infinity or nan
280 self.assertEqualAndEqualSign(pow_op(1.0, -INF), 1.0)
281 self.assertEqualAndEqualSign(pow_op(1.0, -2.0), 1.0)
282 self.assertEqualAndEqualSign(pow_op(1.0, -1.0), 1.0)
283 self.assertEqualAndEqualSign(pow_op(1.0, -0.5), 1.0)
284 self.assertEqualAndEqualSign(pow_op(1.0, -0.0), 1.0)
285 self.assertEqualAndEqualSign(pow_op(1.0, 0.0), 1.0)
286 self.assertEqualAndEqualSign(pow_op(1.0, 0.5), 1.0)
287 self.assertEqualAndEqualSign(pow_op(1.0, 1.0), 1.0)
288 self.assertEqualAndEqualSign(pow_op(1.0, 2.0), 1.0)
289 self.assertEqualAndEqualSign(pow_op(1.0, INF), 1.0)
290 self.assertEqualAndEqualSign(pow_op(1.0, NAN), 1.0)
291
292 # x**+-0 is 1 for any x, even if x is a zero, infinity, or nan
293 self.assertEqualAndEqualSign(pow_op(-INF, 0.0), 1.0)
294 self.assertEqualAndEqualSign(pow_op(-2.0, 0.0), 1.0)
295 self.assertEqualAndEqualSign(pow_op(-1.0, 0.0), 1.0)
296 self.assertEqualAndEqualSign(pow_op(-0.5, 0.0), 1.0)
297 self.assertEqualAndEqualSign(pow_op(-0.0, 0.0), 1.0)
298 self.assertEqualAndEqualSign(pow_op(0.0, 0.0), 1.0)
299 self.assertEqualAndEqualSign(pow_op(0.5, 0.0), 1.0)
300 self.assertEqualAndEqualSign(pow_op(1.0, 0.0), 1.0)
301 self.assertEqualAndEqualSign(pow_op(2.0, 0.0), 1.0)
302 self.assertEqualAndEqualSign(pow_op(INF, 0.0), 1.0)
303 self.assertEqualAndEqualSign(pow_op(NAN, 0.0), 1.0)
304 self.assertEqualAndEqualSign(pow_op(-INF, -0.0), 1.0)
305 self.assertEqualAndEqualSign(pow_op(-2.0, -0.0), 1.0)
306 self.assertEqualAndEqualSign(pow_op(-1.0, -0.0), 1.0)
307 self.assertEqualAndEqualSign(pow_op(-0.5, -0.0), 1.0)
308 self.assertEqualAndEqualSign(pow_op(-0.0, -0.0), 1.0)
309 self.assertEqualAndEqualSign(pow_op(0.0, -0.0), 1.0)
310 self.assertEqualAndEqualSign(pow_op(0.5, -0.0), 1.0)
311 self.assertEqualAndEqualSign(pow_op(1.0, -0.0), 1.0)
312 self.assertEqualAndEqualSign(pow_op(2.0, -0.0), 1.0)
313 self.assertEqualAndEqualSign(pow_op(INF, -0.0), 1.0)
314 self.assertEqualAndEqualSign(pow_op(NAN, -0.0), 1.0)
315
316 # x**y raises ValueError for finite negative x and non-integral y
317 self.assertRaises(ValueError, pow_op, -2.0, -0.5)
318 self.assertRaises(ValueError, pow_op, -2.0, 0.5)
319 self.assertRaises(ValueError, pow_op, -1.0, -0.5)
320 self.assertRaises(ValueError, pow_op, -1.0, 0.5)
321 self.assertRaises(ValueError, pow_op, -0.5, -0.5)
322 self.assertRaises(ValueError, pow_op, -0.5, 0.5)
323
324 # x**-INF is INF for abs(x) < 1
325 self.assertEqualAndEqualSign(pow_op(-0.5, -INF), INF)
326 self.assertEqualAndEqualSign(pow_op(-0.0, -INF), INF)
327 self.assertEqualAndEqualSign(pow_op(0.0, -INF), INF)
328 self.assertEqualAndEqualSign(pow_op(0.5, -INF), INF)
329
330 # x**-INF is 0 for abs(x) > 1
331 self.assertEqualAndEqualSign(pow_op(-INF, -INF), 0.0)
332 self.assertEqualAndEqualSign(pow_op(-2.0, -INF), 0.0)
333 self.assertEqualAndEqualSign(pow_op(2.0, -INF), 0.0)
334 self.assertEqualAndEqualSign(pow_op(INF, -INF), 0.0)
335
336 # x**INF is 0 for abs(x) < 1
337 self.assertEqualAndEqualSign(pow_op(-0.5, INF), 0.0)
338 self.assertEqualAndEqualSign(pow_op(-0.0, INF), 0.0)
339 self.assertEqualAndEqualSign(pow_op(0.0, INF), 0.0)
340 self.assertEqualAndEqualSign(pow_op(0.5, INF), 0.0)
341
342 # x**INF is INF for abs(x) > 1
343 self.assertEqualAndEqualSign(pow_op(-INF, INF), INF)
344 self.assertEqualAndEqualSign(pow_op(-2.0, INF), INF)
345 self.assertEqualAndEqualSign(pow_op(2.0, INF), INF)
346 self.assertEqualAndEqualSign(pow_op(INF, INF), INF)
347
348 # (-INF)**y is -0.0 for y a negative odd integer
349 self.assertEqualAndEqualSign(pow_op(-INF, -1.0), -0.0)
350
351 # (-INF)**y is 0.0 for y negative but not an odd integer
352 self.assertEqualAndEqualSign(pow_op(-INF, -0.5), 0.0)
353 self.assertEqualAndEqualSign(pow_op(-INF, -2.0), 0.0)
354
355 # (-INF)**y is -INF for y a positive odd integer
356 self.assertEqualAndEqualSign(pow_op(-INF, 1.0), -INF)
357
358 # (-INF)**y is INF for y positive but not an odd integer
359 self.assertEqualAndEqualSign(pow_op(-INF, 0.5), INF)
360 self.assertEqualAndEqualSign(pow_op(-INF, 2.0), INF)
361
362 # INF**y is INF for y positive
363 self.assertEqualAndEqualSign(pow_op(INF, 0.5), INF)
364 self.assertEqualAndEqualSign(pow_op(INF, 1.0), INF)
365 self.assertEqualAndEqualSign(pow_op(INF, 2.0), INF)
366
367 # INF**y is 0.0 for y negative
368 self.assertEqualAndEqualSign(pow_op(INF, -2.0), 0.0)
369 self.assertEqualAndEqualSign(pow_op(INF, -1.0), 0.0)
370 self.assertEqualAndEqualSign(pow_op(INF, -0.5), 0.0)
371
372 # basic checks not covered by the special cases above
373 self.assertEqualAndEqualSign(pow_op(-2.0, -2.0), 0.25)
374 self.assertEqualAndEqualSign(pow_op(-2.0, -1.0), -0.5)
375 self.assertEqualAndEqualSign(pow_op(-2.0, -0.0), 1.0)
376 self.assertEqualAndEqualSign(pow_op(-2.0, 0.0), 1.0)
377 self.assertEqualAndEqualSign(pow_op(-2.0, 1.0), -2.0)
378 self.assertEqualAndEqualSign(pow_op(-2.0, 2.0), 4.0)
379 self.assertEqualAndEqualSign(pow_op(-1.0, -2.0), 1.0)
380 self.assertEqualAndEqualSign(pow_op(-1.0, -1.0), -1.0)
381 self.assertEqualAndEqualSign(pow_op(-1.0, -0.0), 1.0)
382 self.assertEqualAndEqualSign(pow_op(-1.0, 0.0), 1.0)
383 self.assertEqualAndEqualSign(pow_op(-1.0, 1.0), -1.0)
384 self.assertEqualAndEqualSign(pow_op(-1.0, 2.0), 1.0)
385 self.assertEqualAndEqualSign(pow_op(2.0, -2.0), 0.25)
386 self.assertEqualAndEqualSign(pow_op(2.0, -1.0), 0.5)
387 self.assertEqualAndEqualSign(pow_op(2.0, -0.0), 1.0)
388 self.assertEqualAndEqualSign(pow_op(2.0, 0.0), 1.0)
389 self.assertEqualAndEqualSign(pow_op(2.0, 1.0), 2.0)
390 self.assertEqualAndEqualSign(pow_op(2.0, 2.0), 4.0)
391
392 # 1 ** large and -1 ** large; some libms apparently
393 # have problems with these
394 self.assertEqualAndEqualSign(pow_op(1.0, -1e100), 1.0)
395 self.assertEqualAndEqualSign(pow_op(1.0, 1e100), 1.0)
396 self.assertEqualAndEqualSign(pow_op(-1.0, -1e100), 1.0)
397 self.assertEqualAndEqualSign(pow_op(-1.0, 1e100), 1.0)
398
399 # check sign for results that underflow to 0
400 self.assertEqualAndEqualSign(pow_op(-2.0, -2000.0), 0.0)
401 self.assertRaises(ValueError, pow_op, -2.0, -2000.5)
402 self.assertEqualAndEqualSign(pow_op(-2.0, -2001.0), -0.0)
403 self.assertEqualAndEqualSign(pow_op(2.0, -2000.0), 0.0)
404 self.assertEqualAndEqualSign(pow_op(2.0, -2000.5), 0.0)
405 self.assertEqualAndEqualSign(pow_op(2.0, -2001.0), 0.0)
406 self.assertEqualAndEqualSign(pow_op(-0.5, 2000.0), 0.0)
407 self.assertRaises(ValueError, pow_op, -0.5, 2000.5)
408 self.assertEqualAndEqualSign(pow_op(-0.5, 2001.0), -0.0)
409 self.assertEqualAndEqualSign(pow_op(0.5, 2000.0), 0.0)
410 self.assertEqualAndEqualSign(pow_op(0.5, 2000.5), 0.0)
411 self.assertEqualAndEqualSign(pow_op(0.5, 2001.0), 0.0)
412
413 # check we don't raise an exception for subnormal results,
414 # and validate signs. Tests currently disabled, since
415 # they fail on systems where a subnormal result from pow
416 # is flushed to zero (e.g. Debian/ia64.)
417 #self.assertTrue(0.0 < pow_op(0.5, 1048) < 1e-315)
418 #self.assertTrue(0.0 < pow_op(-0.5, 1048) < 1e-315)
419 #self.assertTrue(0.0 < pow_op(0.5, 1047) < 1e-315)
420 #self.assertTrue(0.0 > pow_op(-0.5, 1047) > -1e-315)
421 #self.assertTrue(0.0 < pow_op(2.0, -1048) < 1e-315)
422 #self.assertTrue(0.0 < pow_op(-2.0, -1048) < 1e-315)
423 #self.assertTrue(0.0 < pow_op(2.0, -1047) < 1e-315)
424 #self.assertTrue(0.0 > pow_op(-2.0, -1047) > -1e-315)
425
426
Benjamin Peterson0df5a852010-07-02 23:05:27 +0000427@requires_setformat
Michael W. Hudsonba283e22005-05-27 15:23:20 +0000428class FormatFunctionsTestCase(unittest.TestCase):
429
430 def setUp(self):
431 self.save_formats = {'double':float.__getformat__('double'),
432 'float':float.__getformat__('float')}
433
434 def tearDown(self):
435 float.__setformat__('double', self.save_formats['double'])
436 float.__setformat__('float', self.save_formats['float'])
437
438 def test_getformat(self):
Ezio Melottiaa980582010-01-23 23:04:36 +0000439 self.assertIn(float.__getformat__('double'),
440 ['unknown', 'IEEE, big-endian', 'IEEE, little-endian'])
441 self.assertIn(float.__getformat__('float'),
442 ['unknown', 'IEEE, big-endian', 'IEEE, little-endian'])
Michael W. Hudsonba283e22005-05-27 15:23:20 +0000443 self.assertRaises(ValueError, float.__getformat__, 'chicken')
444 self.assertRaises(TypeError, float.__getformat__, 1)
445
446 def test_setformat(self):
447 for t in 'double', 'float':
448 float.__setformat__(t, 'unknown')
449 if self.save_formats[t] == 'IEEE, big-endian':
450 self.assertRaises(ValueError, float.__setformat__,
451 t, 'IEEE, little-endian')
452 elif self.save_formats[t] == 'IEEE, little-endian':
453 self.assertRaises(ValueError, float.__setformat__,
454 t, 'IEEE, big-endian')
455 else:
456 self.assertRaises(ValueError, float.__setformat__,
457 t, 'IEEE, big-endian')
458 self.assertRaises(ValueError, float.__setformat__,
459 t, 'IEEE, little-endian')
460 self.assertRaises(ValueError, float.__setformat__,
461 t, 'chicken')
462 self.assertRaises(ValueError, float.__setformat__,
463 'chicken', 'unknown')
464
465BE_DOUBLE_INF = '\x7f\xf0\x00\x00\x00\x00\x00\x00'
466LE_DOUBLE_INF = ''.join(reversed(BE_DOUBLE_INF))
467BE_DOUBLE_NAN = '\x7f\xf8\x00\x00\x00\x00\x00\x00'
468LE_DOUBLE_NAN = ''.join(reversed(BE_DOUBLE_NAN))
469
470BE_FLOAT_INF = '\x7f\x80\x00\x00'
471LE_FLOAT_INF = ''.join(reversed(BE_FLOAT_INF))
472BE_FLOAT_NAN = '\x7f\xc0\x00\x00'
473LE_FLOAT_NAN = ''.join(reversed(BE_FLOAT_NAN))
474
475# on non-IEEE platforms, attempting to unpack a bit pattern
476# representing an infinity or a NaN should raise an exception.
477
Benjamin Peterson0df5a852010-07-02 23:05:27 +0000478@requires_setformat
Michael W. Hudsonba283e22005-05-27 15:23:20 +0000479class UnknownFormatTestCase(unittest.TestCase):
480 def setUp(self):
481 self.save_formats = {'double':float.__getformat__('double'),
482 'float':float.__getformat__('float')}
483 float.__setformat__('double', 'unknown')
484 float.__setformat__('float', 'unknown')
Tim Peters5d36a552005-06-03 22:40:27 +0000485
Michael W. Hudsonba283e22005-05-27 15:23:20 +0000486 def tearDown(self):
487 float.__setformat__('double', self.save_formats['double'])
488 float.__setformat__('float', self.save_formats['float'])
489
490 def test_double_specials_dont_unpack(self):
491 for fmt, data in [('>d', BE_DOUBLE_INF),
492 ('>d', BE_DOUBLE_NAN),
493 ('<d', LE_DOUBLE_INF),
494 ('<d', LE_DOUBLE_NAN)]:
495 self.assertRaises(ValueError, struct.unpack, fmt, data)
496
497 def test_float_specials_dont_unpack(self):
498 for fmt, data in [('>f', BE_FLOAT_INF),
499 ('>f', BE_FLOAT_NAN),
500 ('<f', LE_FLOAT_INF),
501 ('<f', LE_FLOAT_NAN)]:
502 self.assertRaises(ValueError, struct.unpack, fmt, data)
503
504
505# on an IEEE platform, all we guarantee is that bit patterns
506# representing infinities or NaNs do not raise an exception; all else
507# is accident (today).
Alex Martellid8672aa2007-08-22 21:14:17 +0000508# let's also try to guarantee that -0.0 and 0.0 don't get confused.
Michael W. Hudsonba283e22005-05-27 15:23:20 +0000509
510class IEEEFormatTestCase(unittest.TestCase):
Michael W. Hudsonba283e22005-05-27 15:23:20 +0000511
Benjamin Peterson0df5a852010-07-02 23:05:27 +0000512 @requires_IEEE_754
513 def test_double_specials_do_unpack(self):
514 for fmt, data in [('>d', BE_DOUBLE_INF),
515 ('>d', BE_DOUBLE_NAN),
516 ('<d', LE_DOUBLE_INF),
517 ('<d', LE_DOUBLE_NAN)]:
518 struct.unpack(fmt, data)
Michael W. Hudsonba283e22005-05-27 15:23:20 +0000519
Benjamin Peterson0df5a852010-07-02 23:05:27 +0000520 @requires_IEEE_754
521 def test_float_specials_do_unpack(self):
522 for fmt, data in [('>f', BE_FLOAT_INF),
523 ('>f', BE_FLOAT_NAN),
524 ('<f', LE_FLOAT_INF),
525 ('<f', LE_FLOAT_NAN)]:
526 struct.unpack(fmt, data)
Alex Martellid8672aa2007-08-22 21:14:17 +0000527
Benjamin Peterson0df5a852010-07-02 23:05:27 +0000528 @requires_IEEE_754
529 def test_negative_zero(self):
530 def pos_pos():
531 return 0.0, math.atan2(0.0, -1)
532 def pos_neg():
533 return 0.0, math.atan2(-0.0, -1)
534 def neg_pos():
535 return -0.0, math.atan2(0.0, -1)
536 def neg_neg():
537 return -0.0, math.atan2(-0.0, -1)
Ezio Melotti2623a372010-11-21 13:34:58 +0000538 self.assertEqual(pos_pos(), neg_pos())
539 self.assertEqual(pos_neg(), neg_neg())
Benjamin Peterson0df5a852010-07-02 23:05:27 +0000540
541 @requires_IEEE_754
542 def test_underflow_sign(self):
543 # check that -1e-1000 gives -0.0, not 0.0
Ezio Melotti2623a372010-11-21 13:34:58 +0000544 self.assertEqual(math.atan2(-1e-1000, -1), math.atan2(-0.0, -1))
545 self.assertEqual(math.atan2(float('-1e-1000'), -1),
546 math.atan2(-0.0, -1))
Michael W. Hudsonba283e22005-05-27 15:23:20 +0000547
Eric Smitha985a3a2009-05-05 18:26:08 +0000548 def test_format(self):
549 # these should be rewritten to use both format(x, spec) and
550 # x.__format__(spec)
551
552 self.assertEqual(format(0.0, 'f'), '0.000000')
553
554 # the default is 'g', except for empty format spec
555 self.assertEqual(format(0.0, ''), '0.0')
556 self.assertEqual(format(0.01, ''), '0.01')
557 self.assertEqual(format(0.01, 'g'), '0.01')
558
559 # empty presentation type should format in the same way as str
560 # (issue 5920)
561 x = 100/7.
562 self.assertEqual(format(x, ''), str(x))
563 self.assertEqual(format(x, '-'), str(x))
564 self.assertEqual(format(x, '>'), str(x))
565 self.assertEqual(format(x, '2'), str(x))
566
567 self.assertEqual(format(1.0, 'f'), '1.000000')
568
569 self.assertEqual(format(-1.0, 'f'), '-1.000000')
570
571 self.assertEqual(format( 1.0, ' f'), ' 1.000000')
572 self.assertEqual(format(-1.0, ' f'), '-1.000000')
573 self.assertEqual(format( 1.0, '+f'), '+1.000000')
574 self.assertEqual(format(-1.0, '+f'), '-1.000000')
575
576 # % formatting
577 self.assertEqual(format(-1.0, '%'), '-100.000000%')
578
579 # conversion to string should fail
580 self.assertRaises(ValueError, format, 3.0, "s")
581
582 # other format specifiers shouldn't work on floats,
583 # in particular int specifiers
584 for format_spec in ([chr(x) for x in range(ord('a'), ord('z')+1)] +
585 [chr(x) for x in range(ord('A'), ord('Z')+1)]):
586 if not format_spec in 'eEfFgGn%':
587 self.assertRaises(ValueError, format, 0.0, format_spec)
588 self.assertRaises(ValueError, format, 1.0, format_spec)
589 self.assertRaises(ValueError, format, -1.0, format_spec)
590 self.assertRaises(ValueError, format, 1e100, format_spec)
591 self.assertRaises(ValueError, format, -1e100, format_spec)
592 self.assertRaises(ValueError, format, 1e-100, format_spec)
593 self.assertRaises(ValueError, format, -1e-100, format_spec)
594
Eric Smithc4ab8332009-11-29 17:40:57 +0000595 # issue 3382: 'f' and 'F' with inf's and nan's
596 self.assertEqual('{0:f}'.format(INF), 'inf')
597 self.assertEqual('{0:F}'.format(INF), 'INF')
598 self.assertEqual('{0:f}'.format(-INF), '-inf')
599 self.assertEqual('{0:F}'.format(-INF), '-INF')
600 self.assertEqual('{0:f}'.format(NAN), 'nan')
601 self.assertEqual('{0:F}'.format(NAN), 'NAN')
602
Benjamin Peterson0df5a852010-07-02 23:05:27 +0000603 @requires_IEEE_754
Mark Dickinson61a0d052009-04-29 21:57:15 +0000604 def test_format_testfile(self):
Brian Curtinee139682010-10-31 00:08:27 +0000605 with open(format_testfile) as testfile:
606 for line in open(format_testfile):
607 if line.startswith('--'):
608 continue
609 line = line.strip()
610 if not line:
611 continue
Mark Dickinson61a0d052009-04-29 21:57:15 +0000612
Brian Curtinee139682010-10-31 00:08:27 +0000613 lhs, rhs = map(str.strip, line.split('->'))
614 fmt, arg = lhs.split()
615 arg = float(arg)
616 self.assertEqual(fmt % arg, rhs)
617 if not math.isnan(arg) and copysign(1.0, arg) > 0.0:
618 self.assertEqual(fmt % -arg, '-' + rhs)
Mark Dickinson61a0d052009-04-29 21:57:15 +0000619
Mark Dickinson92fcc9c2009-04-29 20:41:00 +0000620 def test_issue5864(self):
Ezio Melotti2623a372010-11-21 13:34:58 +0000621 self.assertEqual(format(123.456, '.4'), '123.5')
622 self.assertEqual(format(1234.56, '.4'), '1.235e+03')
623 self.assertEqual(format(12345.6, '.4'), '1.235e+04')
Mark Dickinson92fcc9c2009-04-29 20:41:00 +0000624
Christian Heimes284d9272007-12-10 22:28:56 +0000625class ReprTestCase(unittest.TestCase):
626 def test_repr(self):
627 floats_file = open(os.path.join(os.path.split(__file__)[0],
628 'floating_points.txt'))
629 for line in floats_file:
630 line = line.strip()
631 if not line or line.startswith('#'):
632 continue
633 v = eval(line)
634 self.assertEqual(v, eval(repr(v)))
635 floats_file.close()
636
Mark Dickinson3194d142010-01-08 16:53:56 +0000637 @unittest.skipUnless(getattr(sys, 'float_repr_style', '') == 'short',
638 "applies only when using short float repr style")
639 def test_short_repr(self):
640 # test short float repr introduced in Python 3.1. One aspect
641 # of this repr is that we get some degree of str -> float ->
642 # str roundtripping. In particular, for any numeric string
643 # containing 15 or fewer significant digits, those exact same
644 # digits (modulo trailing zeros) should appear in the output.
645 # No more repr(0.03) -> "0.029999999999999999"!
646
647 test_strings = [
648 # output always includes *either* a decimal point and at
649 # least one digit after that point, or an exponent.
650 '0.0',
651 '1.0',
652 '0.01',
653 '0.02',
654 '0.03',
655 '0.04',
656 '0.05',
657 '1.23456789',
658 '10.0',
659 '100.0',
660 # values >= 1e16 get an exponent...
661 '1000000000000000.0',
662 '9999999999999990.0',
663 '1e+16',
664 '1e+17',
665 # ... and so do values < 1e-4
666 '0.001',
667 '0.001001',
668 '0.00010000000000001',
669 '0.0001',
670 '9.999999999999e-05',
671 '1e-05',
672 # values designed to provoke failure if the FPU rounding
673 # precision isn't set correctly
674 '8.72293771110361e+25',
675 '7.47005307342313e+26',
676 '2.86438000439698e+28',
677 '8.89142905246179e+28',
678 '3.08578087079232e+35',
679 ]
680
681 for s in test_strings:
682 negs = '-'+s
683 self.assertEqual(s, repr(float(s)))
684 self.assertEqual(negs, repr(float(negs)))
685
Benjamin Peterson0df5a852010-07-02 23:05:27 +0000686
687@requires_IEEE_754
Mark Dickinsonbd15a062009-11-18 19:33:35 +0000688class RoundTestCase(unittest.TestCase):
689 def test_second_argument_type(self):
690 # any type with an __index__ method should be permitted as
691 # a second argument
692 self.assertAlmostEqual(round(12.34, True), 12.3)
693
694 class MyIndex(object):
695 def __index__(self): return 4
696 self.assertAlmostEqual(round(-0.123456, MyIndex()), -0.1235)
697 # but floats should be illegal
698 self.assertRaises(TypeError, round, 3.14159, 2.0)
699
700 def test_inf_nan(self):
701 # rounding an infinity or nan returns the same number;
702 # (in py3k, rounding an infinity or nan raises an error,
703 # since the result can't be represented as a long).
704 self.assertEqual(round(INF), INF)
705 self.assertEqual(round(-INF), -INF)
706 self.assertTrue(math.isnan(round(NAN)))
707 for n in range(-5, 5):
708 self.assertEqual(round(INF, n), INF)
709 self.assertEqual(round(-INF, n), -INF)
710 self.assertTrue(math.isnan(round(NAN, n)))
711
Mark Dickinsonbce78372009-11-24 10:54:58 +0000712 self.assertRaises(TypeError, round, INF, 0.0)
713 self.assertRaises(TypeError, round, -INF, 1.0)
714 self.assertRaises(TypeError, round, NAN, "ceci n'est pas un integer")
715 self.assertRaises(TypeError, round, -0.0, 1j)
716
Mark Dickinsonbd15a062009-11-18 19:33:35 +0000717 def test_large_n(self):
718 for n in [324, 325, 400, 2**31-1, 2**31, 2**32, 2**100]:
719 self.assertEqual(round(123.456, n), 123.456)
720 self.assertEqual(round(-123.456, n), -123.456)
721 self.assertEqual(round(1e300, n), 1e300)
722 self.assertEqual(round(1e-320, n), 1e-320)
723 self.assertEqual(round(1e150, 300), 1e150)
724 self.assertEqual(round(1e300, 307), 1e300)
725 self.assertEqual(round(-3.1415, 308), -3.1415)
726 self.assertEqual(round(1e150, 309), 1e150)
727 self.assertEqual(round(1.4e-315, 315), 1e-315)
728
729 def test_small_n(self):
730 for n in [-308, -309, -400, 1-2**31, -2**31, -2**31-1, -2**100]:
731 self.assertEqual(round(123.456, n), 0.0)
732 self.assertEqual(round(-123.456, n), -0.0)
733 self.assertEqual(round(1e300, n), 0.0)
734 self.assertEqual(round(1e-320, n), 0.0)
735
736 def test_overflow(self):
737 self.assertRaises(OverflowError, round, 1.6e308, -308)
738 self.assertRaises(OverflowError, round, -1.7e308, -308)
739
740 @unittest.skipUnless(getattr(sys, 'float_repr_style', '') == 'short',
741 "test applies only when using short float repr style")
742 def test_previous_round_bugs(self):
743 # particular cases that have occurred in bug reports
744 self.assertEqual(round(562949953421312.5, 1),
745 562949953421312.5)
746 self.assertEqual(round(56294995342131.5, 3),
747 56294995342131.5)
748
749 @unittest.skipUnless(getattr(sys, 'float_repr_style', '') == 'short',
750 "test applies only when using short float repr style")
751 def test_halfway_cases(self):
752 # Halfway cases need special attention, since the current
753 # implementation has to deal with them specially. Note that
754 # 2.x rounds halfway values up (i.e., away from zero) while
755 # 3.x does round-half-to-even.
756 self.assertAlmostEqual(round(0.125, 2), 0.13)
757 self.assertAlmostEqual(round(0.375, 2), 0.38)
758 self.assertAlmostEqual(round(0.625, 2), 0.63)
759 self.assertAlmostEqual(round(0.875, 2), 0.88)
760 self.assertAlmostEqual(round(-0.125, 2), -0.13)
761 self.assertAlmostEqual(round(-0.375, 2), -0.38)
762 self.assertAlmostEqual(round(-0.625, 2), -0.63)
763 self.assertAlmostEqual(round(-0.875, 2), -0.88)
764
765 self.assertAlmostEqual(round(0.25, 1), 0.3)
766 self.assertAlmostEqual(round(0.75, 1), 0.8)
767 self.assertAlmostEqual(round(-0.25, 1), -0.3)
768 self.assertAlmostEqual(round(-0.75, 1), -0.8)
769
770 self.assertEqual(round(-6.5, 0), -7.0)
771 self.assertEqual(round(-5.5, 0), -6.0)
772 self.assertEqual(round(-1.5, 0), -2.0)
773 self.assertEqual(round(-0.5, 0), -1.0)
774 self.assertEqual(round(0.5, 0), 1.0)
775 self.assertEqual(round(1.5, 0), 2.0)
776 self.assertEqual(round(2.5, 0), 3.0)
777 self.assertEqual(round(3.5, 0), 4.0)
778 self.assertEqual(round(4.5, 0), 5.0)
779 self.assertEqual(round(5.5, 0), 6.0)
780 self.assertEqual(round(6.5, 0), 7.0)
781
782 # same but without an explicit second argument; in 3.x these
783 # will give integers
784 self.assertEqual(round(-6.5), -7.0)
785 self.assertEqual(round(-5.5), -6.0)
786 self.assertEqual(round(-1.5), -2.0)
787 self.assertEqual(round(-0.5), -1.0)
788 self.assertEqual(round(0.5), 1.0)
789 self.assertEqual(round(1.5), 2.0)
790 self.assertEqual(round(2.5), 3.0)
791 self.assertEqual(round(3.5), 4.0)
792 self.assertEqual(round(4.5), 5.0)
793 self.assertEqual(round(5.5), 6.0)
794 self.assertEqual(round(6.5), 7.0)
795
796 self.assertEqual(round(-25.0, -1), -30.0)
797 self.assertEqual(round(-15.0, -1), -20.0)
798 self.assertEqual(round(-5.0, -1), -10.0)
799 self.assertEqual(round(5.0, -1), 10.0)
800 self.assertEqual(round(15.0, -1), 20.0)
801 self.assertEqual(round(25.0, -1), 30.0)
802 self.assertEqual(round(35.0, -1), 40.0)
803 self.assertEqual(round(45.0, -1), 50.0)
804 self.assertEqual(round(55.0, -1), 60.0)
805 self.assertEqual(round(65.0, -1), 70.0)
806 self.assertEqual(round(75.0, -1), 80.0)
807 self.assertEqual(round(85.0, -1), 90.0)
808 self.assertEqual(round(95.0, -1), 100.0)
809 self.assertEqual(round(12325.0, -1), 12330.0)
810
811 self.assertEqual(round(350.0, -2), 400.0)
812 self.assertEqual(round(450.0, -2), 500.0)
813
814 self.assertAlmostEqual(round(0.5e21, -21), 1e21)
815 self.assertAlmostEqual(round(1.5e21, -21), 2e21)
816 self.assertAlmostEqual(round(2.5e21, -21), 3e21)
817 self.assertAlmostEqual(round(5.5e21, -21), 6e21)
818 self.assertAlmostEqual(round(8.5e21, -21), 9e21)
819
820 self.assertAlmostEqual(round(-1.5e22, -22), -2e22)
821 self.assertAlmostEqual(round(-0.5e22, -22), -1e22)
822 self.assertAlmostEqual(round(0.5e22, -22), 1e22)
823 self.assertAlmostEqual(round(1.5e22, -22), 2e22)
824
Benjamin Peterson0df5a852010-07-02 23:05:27 +0000825
826 @requires_IEEE_754
Eric Smithf2bf0d22009-12-02 17:43:06 +0000827 def test_format_specials(self):
828 # Test formatting of nans and infs.
829
830 def test(fmt, value, expected):
831 # Test with both % and format().
832 self.assertEqual(fmt % value, expected, fmt)
833 if not '#' in fmt:
834 # Until issue 7094 is implemented, format() for floats doesn't
835 # support '#' formatting
836 fmt = fmt[1:] # strip off the %
837 self.assertEqual(format(value, fmt), expected, fmt)
838
839 for fmt in ['%e', '%f', '%g', '%.0e', '%.6f', '%.20g',
840 '%#e', '%#f', '%#g', '%#.20e', '%#.15f', '%#.3g']:
841 pfmt = '%+' + fmt[1:]
842 sfmt = '% ' + fmt[1:]
843 test(fmt, INF, 'inf')
844 test(fmt, -INF, '-inf')
845 test(fmt, NAN, 'nan')
846 test(fmt, -NAN, 'nan')
847 # When asking for a sign, it's always provided. nans are
848 # always positive.
849 test(pfmt, INF, '+inf')
850 test(pfmt, -INF, '-inf')
851 test(pfmt, NAN, '+nan')
852 test(pfmt, -NAN, '+nan')
853 # When using ' ' for a sign code, only infs can be negative.
854 # Others have a space.
855 test(sfmt, INF, ' inf')
856 test(sfmt, -INF, '-inf')
857 test(sfmt, NAN, ' nan')
858 test(sfmt, -NAN, ' nan')
859
Mark Dickinsonbd15a062009-11-18 19:33:35 +0000860
Christian Heimes0a8143f2007-12-18 23:22:54 +0000861# Beginning with Python 2.6 float has cross platform compatible
Mark Dickinsonbf9f4d82008-07-05 11:33:52 +0000862# ways to create and represent inf and nan
Christian Heimes0a8143f2007-12-18 23:22:54 +0000863class InfNanTest(unittest.TestCase):
864 def test_inf_from_str(self):
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000865 self.assertTrue(isinf(float("inf")))
866 self.assertTrue(isinf(float("+inf")))
867 self.assertTrue(isinf(float("-inf")))
868 self.assertTrue(isinf(float("infinity")))
869 self.assertTrue(isinf(float("+infinity")))
870 self.assertTrue(isinf(float("-infinity")))
Christian Heimes0a8143f2007-12-18 23:22:54 +0000871
872 self.assertEqual(repr(float("inf")), "inf")
873 self.assertEqual(repr(float("+inf")), "inf")
874 self.assertEqual(repr(float("-inf")), "-inf")
Mark Dickinsonbf9f4d82008-07-05 11:33:52 +0000875 self.assertEqual(repr(float("infinity")), "inf")
876 self.assertEqual(repr(float("+infinity")), "inf")
877 self.assertEqual(repr(float("-infinity")), "-inf")
Christian Heimes0a8143f2007-12-18 23:22:54 +0000878
879 self.assertEqual(repr(float("INF")), "inf")
880 self.assertEqual(repr(float("+Inf")), "inf")
881 self.assertEqual(repr(float("-iNF")), "-inf")
Mark Dickinsonbf9f4d82008-07-05 11:33:52 +0000882 self.assertEqual(repr(float("Infinity")), "inf")
883 self.assertEqual(repr(float("+iNfInItY")), "inf")
884 self.assertEqual(repr(float("-INFINITY")), "-inf")
Christian Heimes0a8143f2007-12-18 23:22:54 +0000885
886 self.assertEqual(str(float("inf")), "inf")
887 self.assertEqual(str(float("+inf")), "inf")
888 self.assertEqual(str(float("-inf")), "-inf")
Mark Dickinsonbf9f4d82008-07-05 11:33:52 +0000889 self.assertEqual(str(float("infinity")), "inf")
890 self.assertEqual(str(float("+infinity")), "inf")
891 self.assertEqual(str(float("-infinity")), "-inf")
Christian Heimes0a8143f2007-12-18 23:22:54 +0000892
893 self.assertRaises(ValueError, float, "info")
894 self.assertRaises(ValueError, float, "+info")
895 self.assertRaises(ValueError, float, "-info")
896 self.assertRaises(ValueError, float, "in")
897 self.assertRaises(ValueError, float, "+in")
898 self.assertRaises(ValueError, float, "-in")
Mark Dickinsonbf9f4d82008-07-05 11:33:52 +0000899 self.assertRaises(ValueError, float, "infinit")
900 self.assertRaises(ValueError, float, "+Infin")
901 self.assertRaises(ValueError, float, "-INFI")
902 self.assertRaises(ValueError, float, "infinitys")
Christian Heimes0a8143f2007-12-18 23:22:54 +0000903
904 def test_inf_as_str(self):
905 self.assertEqual(repr(1e300 * 1e300), "inf")
906 self.assertEqual(repr(-1e300 * 1e300), "-inf")
907
908 self.assertEqual(str(1e300 * 1e300), "inf")
909 self.assertEqual(str(-1e300 * 1e300), "-inf")
910
911 def test_nan_from_str(self):
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000912 self.assertTrue(isnan(float("nan")))
913 self.assertTrue(isnan(float("+nan")))
914 self.assertTrue(isnan(float("-nan")))
Christian Heimes0a8143f2007-12-18 23:22:54 +0000915
916 self.assertEqual(repr(float("nan")), "nan")
917 self.assertEqual(repr(float("+nan")), "nan")
918 self.assertEqual(repr(float("-nan")), "nan")
919
920 self.assertEqual(repr(float("NAN")), "nan")
921 self.assertEqual(repr(float("+NAn")), "nan")
922 self.assertEqual(repr(float("-NaN")), "nan")
923
924 self.assertEqual(str(float("nan")), "nan")
925 self.assertEqual(str(float("+nan")), "nan")
926 self.assertEqual(str(float("-nan")), "nan")
927
928 self.assertRaises(ValueError, float, "nana")
929 self.assertRaises(ValueError, float, "+nana")
930 self.assertRaises(ValueError, float, "-nana")
931 self.assertRaises(ValueError, float, "na")
932 self.assertRaises(ValueError, float, "+na")
933 self.assertRaises(ValueError, float, "-na")
934
935 def test_nan_as_str(self):
936 self.assertEqual(repr(1e300 * 1e300 * 0), "nan")
937 self.assertEqual(repr(-1e300 * 1e300 * 0), "nan")
938
939 self.assertEqual(str(1e300 * 1e300 * 0), "nan")
940 self.assertEqual(str(-1e300 * 1e300 * 0), "nan")
Christian Heimes284d9272007-12-10 22:28:56 +0000941
Christian Heimes6f341092008-04-18 23:13:07 +0000942 def notest_float_nan(self):
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000943 self.assertTrue(NAN.is_nan())
944 self.assertFalse(INF.is_nan())
945 self.assertFalse((0.).is_nan())
Christian Heimes6f341092008-04-18 23:13:07 +0000946
947 def notest_float_inf(self):
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000948 self.assertTrue(INF.is_inf())
949 self.assertFalse(NAN.is_inf())
950 self.assertFalse((0.).is_inf())
Christian Heimes6f341092008-04-18 23:13:07 +0000951
Mark Dickinson5e0c2742010-04-05 18:07:51 +0000952 def test_hash_inf(self):
953 # the actual values here should be regarded as an
954 # implementation detail, but they need to be
955 # identical to those used in the Decimal module.
956 self.assertEqual(hash(float('inf')), 314159)
957 self.assertEqual(hash(float('-inf')), -271828)
958 self.assertEqual(hash(float('nan')), 0)
959
960
Mark Dickinson7103aa42008-07-15 19:08:33 +0000961fromHex = float.fromhex
962toHex = float.hex
963class HexFloatTestCase(unittest.TestCase):
964 MAX = fromHex('0x.fffffffffffff8p+1024') # max normal
965 MIN = fromHex('0x1p-1022') # min normal
966 TINY = fromHex('0x0.0000000000001p-1022') # min subnormal
967 EPS = fromHex('0x0.0000000000001p0') # diff between 1.0 and next float up
968
969 def identical(self, x, y):
970 # check that floats x and y are identical, or that both
971 # are NaNs
972 if isnan(x) or isnan(y):
973 if isnan(x) == isnan(y):
974 return
975 elif x == y and (x != 0.0 or copysign(1.0, x) == copysign(1.0, y)):
976 return
977 self.fail('%r not identical to %r' % (x, y))
978
979 def test_ends(self):
Mark Dickinson62764562008-07-15 21:55:23 +0000980 self.identical(self.MIN, ldexp(1.0, -1022))
981 self.identical(self.TINY, ldexp(1.0, -1074))
982 self.identical(self.EPS, ldexp(1.0, -52))
983 self.identical(self.MAX, 2.*(ldexp(1.0, 1023) - ldexp(1.0, 970)))
Mark Dickinson7103aa42008-07-15 19:08:33 +0000984
985 def test_invalid_inputs(self):
986 invalid_inputs = [
987 'infi', # misspelt infinities and nans
988 '-Infinit',
989 '++inf',
990 '-+Inf',
991 '--nan',
992 '+-NaN',
993 'snan',
994 'NaNs',
995 'nna',
Mark Dickinsonb1d45852009-05-11 15:33:08 +0000996 'an',
997 'nf',
998 'nfinity',
999 'inity',
1000 'iinity',
Mark Dickinson7103aa42008-07-15 19:08:33 +00001001 '0xnan',
1002 '',
1003 ' ',
1004 'x1.0p0',
1005 '0xX1.0p0',
1006 '+ 0x1.0p0', # internal whitespace
1007 '- 0x1.0p0',
1008 '0 x1.0p0',
1009 '0x 1.0p0',
1010 '0x1 2.0p0',
1011 '+0x1 .0p0',
1012 '0x1. 0p0',
1013 '-0x1.0 1p0',
1014 '-0x1.0 p0',
1015 '+0x1.0p +0',
1016 '0x1.0p -0',
1017 '0x1.0p 0',
1018 '+0x1.0p+ 0',
1019 '-0x1.0p- 0',
1020 '++0x1.0p-0', # double signs
1021 '--0x1.0p0',
1022 '+-0x1.0p+0',
1023 '-+0x1.0p0',
1024 '0x1.0p++0',
1025 '+0x1.0p+-0',
1026 '-0x1.0p-+0',
1027 '0x1.0p--0',
1028 '0x1.0.p0',
1029 '0x.p0', # no hex digits before or after point
1030 '0x1,p0', # wrong decimal point character
1031 '0x1pa',
1032 u'0x1p\uff10', # fullwidth Unicode digits
1033 u'\uff10x1p0',
1034 u'0x\uff11p0',
1035 u'0x1.\uff10p0',
1036 '0x1p0 \n 0x2p0',
1037 '0x1p0\0 0x1p0', # embedded null byte is not end of string
1038 ]
1039 for x in invalid_inputs:
Mark Dickinson892429b2008-08-21 20:02:24 +00001040 try:
1041 result = fromHex(x)
1042 except ValueError:
1043 pass
1044 else:
1045 self.fail('Expected float.fromhex(%r) to raise ValueError; '
1046 'got %r instead' % (x, result))
Mark Dickinson7103aa42008-07-15 19:08:33 +00001047
1048
Mark Dickinsonb1d45852009-05-11 15:33:08 +00001049 def test_whitespace(self):
1050 value_pairs = [
1051 ('inf', INF),
1052 ('-Infinity', -INF),
1053 ('nan', NAN),
1054 ('1.0', 1.0),
1055 ('-0x.2', -0.125),
1056 ('-0.0', -0.0)
1057 ]
1058 whitespace = [
1059 '',
1060 ' ',
1061 '\t',
1062 '\n',
1063 '\n \t',
1064 '\f',
1065 '\v',
1066 '\r'
1067 ]
1068 for inp, expected in value_pairs:
1069 for lead in whitespace:
1070 for trail in whitespace:
1071 got = fromHex(lead + inp + trail)
1072 self.identical(got, expected)
1073
1074
Mark Dickinson7103aa42008-07-15 19:08:33 +00001075 def test_from_hex(self):
1076 MIN = self.MIN;
1077 MAX = self.MAX;
1078 TINY = self.TINY;
1079 EPS = self.EPS;
1080
1081 # two spellings of infinity, with optional signs; case-insensitive
1082 self.identical(fromHex('inf'), INF)
1083 self.identical(fromHex('+Inf'), INF)
1084 self.identical(fromHex('-INF'), -INF)
1085 self.identical(fromHex('iNf'), INF)
1086 self.identical(fromHex('Infinity'), INF)
1087 self.identical(fromHex('+INFINITY'), INF)
1088 self.identical(fromHex('-infinity'), -INF)
1089 self.identical(fromHex('-iNFiNitY'), -INF)
1090
1091 # nans with optional sign; case insensitive
1092 self.identical(fromHex('nan'), NAN)
1093 self.identical(fromHex('+NaN'), NAN)
1094 self.identical(fromHex('-NaN'), NAN)
1095 self.identical(fromHex('-nAN'), NAN)
1096
1097 # variations in input format
1098 self.identical(fromHex('1'), 1.0)
1099 self.identical(fromHex('+1'), 1.0)
1100 self.identical(fromHex('1.'), 1.0)
1101 self.identical(fromHex('1.0'), 1.0)
1102 self.identical(fromHex('1.0p0'), 1.0)
1103 self.identical(fromHex('01'), 1.0)
1104 self.identical(fromHex('01.'), 1.0)
1105 self.identical(fromHex('0x1'), 1.0)
1106 self.identical(fromHex('0x1.'), 1.0)
1107 self.identical(fromHex('0x1.0'), 1.0)
1108 self.identical(fromHex('+0x1.0'), 1.0)
1109 self.identical(fromHex('0x1p0'), 1.0)
1110 self.identical(fromHex('0X1p0'), 1.0)
1111 self.identical(fromHex('0X1P0'), 1.0)
1112 self.identical(fromHex('0x1P0'), 1.0)
1113 self.identical(fromHex('0x1.p0'), 1.0)
1114 self.identical(fromHex('0x1.0p0'), 1.0)
1115 self.identical(fromHex('0x.1p4'), 1.0)
1116 self.identical(fromHex('0x.1p04'), 1.0)
1117 self.identical(fromHex('0x.1p004'), 1.0)
1118 self.identical(fromHex('0x1p+0'), 1.0)
1119 self.identical(fromHex('0x1P-0'), 1.0)
1120 self.identical(fromHex('+0x1p0'), 1.0)
1121 self.identical(fromHex('0x01p0'), 1.0)
1122 self.identical(fromHex('0x1p00'), 1.0)
1123 self.identical(fromHex(u'0x1p0'), 1.0)
1124 self.identical(fromHex(' 0x1p0 '), 1.0)
1125 self.identical(fromHex('\n 0x1p0'), 1.0)
1126 self.identical(fromHex('0x1p0 \t'), 1.0)
1127 self.identical(fromHex('0xap0'), 10.0)
1128 self.identical(fromHex('0xAp0'), 10.0)
1129 self.identical(fromHex('0xaP0'), 10.0)
1130 self.identical(fromHex('0xAP0'), 10.0)
1131 self.identical(fromHex('0xbep0'), 190.0)
1132 self.identical(fromHex('0xBep0'), 190.0)
1133 self.identical(fromHex('0xbEp0'), 190.0)
1134 self.identical(fromHex('0XBE0P-4'), 190.0)
1135 self.identical(fromHex('0xBEp0'), 190.0)
1136 self.identical(fromHex('0xB.Ep4'), 190.0)
1137 self.identical(fromHex('0x.BEp8'), 190.0)
1138 self.identical(fromHex('0x.0BEp12'), 190.0)
1139
1140 # moving the point around
1141 pi = fromHex('0x1.921fb54442d18p1')
1142 self.identical(fromHex('0x.006487ed5110b46p11'), pi)
1143 self.identical(fromHex('0x.00c90fdaa22168cp10'), pi)
1144 self.identical(fromHex('0x.01921fb54442d18p9'), pi)
1145 self.identical(fromHex('0x.03243f6a8885a3p8'), pi)
1146 self.identical(fromHex('0x.06487ed5110b46p7'), pi)
1147 self.identical(fromHex('0x.0c90fdaa22168cp6'), pi)
1148 self.identical(fromHex('0x.1921fb54442d18p5'), pi)
1149 self.identical(fromHex('0x.3243f6a8885a3p4'), pi)
1150 self.identical(fromHex('0x.6487ed5110b46p3'), pi)
1151 self.identical(fromHex('0x.c90fdaa22168cp2'), pi)
1152 self.identical(fromHex('0x1.921fb54442d18p1'), pi)
1153 self.identical(fromHex('0x3.243f6a8885a3p0'), pi)
1154 self.identical(fromHex('0x6.487ed5110b46p-1'), pi)
1155 self.identical(fromHex('0xc.90fdaa22168cp-2'), pi)
1156 self.identical(fromHex('0x19.21fb54442d18p-3'), pi)
1157 self.identical(fromHex('0x32.43f6a8885a3p-4'), pi)
1158 self.identical(fromHex('0x64.87ed5110b46p-5'), pi)
1159 self.identical(fromHex('0xc9.0fdaa22168cp-6'), pi)
1160 self.identical(fromHex('0x192.1fb54442d18p-7'), pi)
1161 self.identical(fromHex('0x324.3f6a8885a3p-8'), pi)
1162 self.identical(fromHex('0x648.7ed5110b46p-9'), pi)
1163 self.identical(fromHex('0xc90.fdaa22168cp-10'), pi)
1164 self.identical(fromHex('0x1921.fb54442d18p-11'), pi)
1165 # ...
1166 self.identical(fromHex('0x1921fb54442d1.8p-47'), pi)
1167 self.identical(fromHex('0x3243f6a8885a3p-48'), pi)
1168 self.identical(fromHex('0x6487ed5110b46p-49'), pi)
1169 self.identical(fromHex('0xc90fdaa22168cp-50'), pi)
1170 self.identical(fromHex('0x1921fb54442d18p-51'), pi)
1171 self.identical(fromHex('0x3243f6a8885a30p-52'), pi)
1172 self.identical(fromHex('0x6487ed5110b460p-53'), pi)
1173 self.identical(fromHex('0xc90fdaa22168c0p-54'), pi)
1174 self.identical(fromHex('0x1921fb54442d180p-55'), pi)
1175
1176
1177 # results that should overflow...
1178 self.assertRaises(OverflowError, fromHex, '-0x1p1024')
1179 self.assertRaises(OverflowError, fromHex, '0x1p+1025')
1180 self.assertRaises(OverflowError, fromHex, '+0X1p1030')
1181 self.assertRaises(OverflowError, fromHex, '-0x1p+1100')
1182 self.assertRaises(OverflowError, fromHex, '0X1p123456789123456789')
1183 self.assertRaises(OverflowError, fromHex, '+0X.8p+1025')
1184 self.assertRaises(OverflowError, fromHex, '+0x0.8p1025')
1185 self.assertRaises(OverflowError, fromHex, '-0x0.4p1026')
1186 self.assertRaises(OverflowError, fromHex, '0X2p+1023')
1187 self.assertRaises(OverflowError, fromHex, '0x2.p1023')
1188 self.assertRaises(OverflowError, fromHex, '-0x2.0p+1023')
1189 self.assertRaises(OverflowError, fromHex, '+0X4p+1022')
1190 self.assertRaises(OverflowError, fromHex, '0x1.ffffffffffffffp+1023')
1191 self.assertRaises(OverflowError, fromHex, '-0X1.fffffffffffff9p1023')
1192 self.assertRaises(OverflowError, fromHex, '0X1.fffffffffffff8p1023')
1193 self.assertRaises(OverflowError, fromHex, '+0x3.fffffffffffffp1022')
1194 self.assertRaises(OverflowError, fromHex, '0x3fffffffffffffp+970')
1195 self.assertRaises(OverflowError, fromHex, '0x10000000000000000p960')
1196 self.assertRaises(OverflowError, fromHex, '-0Xffffffffffffffffp960')
1197
1198 # ...and those that round to +-max float
1199 self.identical(fromHex('+0x1.fffffffffffffp+1023'), MAX)
1200 self.identical(fromHex('-0X1.fffffffffffff7p1023'), -MAX)
1201 self.identical(fromHex('0X1.fffffffffffff7fffffffffffffp1023'), MAX)
1202
1203 # zeros
1204 self.identical(fromHex('0x0p0'), 0.0)
1205 self.identical(fromHex('0x0p1000'), 0.0)
1206 self.identical(fromHex('-0x0p1023'), -0.0)
1207 self.identical(fromHex('0X0p1024'), 0.0)
1208 self.identical(fromHex('-0x0p1025'), -0.0)
1209 self.identical(fromHex('0X0p2000'), 0.0)
1210 self.identical(fromHex('0x0p123456789123456789'), 0.0)
1211 self.identical(fromHex('-0X0p-0'), -0.0)
1212 self.identical(fromHex('-0X0p-1000'), -0.0)
1213 self.identical(fromHex('0x0p-1023'), 0.0)
1214 self.identical(fromHex('-0X0p-1024'), -0.0)
1215 self.identical(fromHex('-0x0p-1025'), -0.0)
1216 self.identical(fromHex('-0x0p-1072'), -0.0)
1217 self.identical(fromHex('0X0p-1073'), 0.0)
1218 self.identical(fromHex('-0x0p-1074'), -0.0)
1219 self.identical(fromHex('0x0p-1075'), 0.0)
1220 self.identical(fromHex('0X0p-1076'), 0.0)
1221 self.identical(fromHex('-0X0p-2000'), -0.0)
1222 self.identical(fromHex('-0x0p-123456789123456789'), -0.0)
1223
1224 # values that should underflow to 0
1225 self.identical(fromHex('0X1p-1075'), 0.0)
1226 self.identical(fromHex('-0X1p-1075'), -0.0)
1227 self.identical(fromHex('-0x1p-123456789123456789'), -0.0)
1228 self.identical(fromHex('0x1.00000000000000001p-1075'), TINY)
1229 self.identical(fromHex('-0x1.1p-1075'), -TINY)
1230 self.identical(fromHex('0x1.fffffffffffffffffp-1075'), TINY)
1231
1232 # check round-half-even is working correctly near 0 ...
1233 self.identical(fromHex('0x1p-1076'), 0.0)
1234 self.identical(fromHex('0X2p-1076'), 0.0)
1235 self.identical(fromHex('0X3p-1076'), TINY)
1236 self.identical(fromHex('0x4p-1076'), TINY)
1237 self.identical(fromHex('0X5p-1076'), TINY)
1238 self.identical(fromHex('0X6p-1076'), 2*TINY)
1239 self.identical(fromHex('0x7p-1076'), 2*TINY)
1240 self.identical(fromHex('0X8p-1076'), 2*TINY)
1241 self.identical(fromHex('0X9p-1076'), 2*TINY)
1242 self.identical(fromHex('0xap-1076'), 2*TINY)
1243 self.identical(fromHex('0Xbp-1076'), 3*TINY)
1244 self.identical(fromHex('0xcp-1076'), 3*TINY)
1245 self.identical(fromHex('0Xdp-1076'), 3*TINY)
1246 self.identical(fromHex('0Xep-1076'), 4*TINY)
1247 self.identical(fromHex('0xfp-1076'), 4*TINY)
1248 self.identical(fromHex('0x10p-1076'), 4*TINY)
1249 self.identical(fromHex('-0x1p-1076'), -0.0)
1250 self.identical(fromHex('-0X2p-1076'), -0.0)
1251 self.identical(fromHex('-0x3p-1076'), -TINY)
1252 self.identical(fromHex('-0X4p-1076'), -TINY)
1253 self.identical(fromHex('-0x5p-1076'), -TINY)
1254 self.identical(fromHex('-0x6p-1076'), -2*TINY)
1255 self.identical(fromHex('-0X7p-1076'), -2*TINY)
1256 self.identical(fromHex('-0X8p-1076'), -2*TINY)
1257 self.identical(fromHex('-0X9p-1076'), -2*TINY)
1258 self.identical(fromHex('-0Xap-1076'), -2*TINY)
1259 self.identical(fromHex('-0xbp-1076'), -3*TINY)
1260 self.identical(fromHex('-0xcp-1076'), -3*TINY)
1261 self.identical(fromHex('-0Xdp-1076'), -3*TINY)
1262 self.identical(fromHex('-0xep-1076'), -4*TINY)
1263 self.identical(fromHex('-0Xfp-1076'), -4*TINY)
1264 self.identical(fromHex('-0X10p-1076'), -4*TINY)
1265
1266 # ... and near MIN ...
1267 self.identical(fromHex('0x0.ffffffffffffd6p-1022'), MIN-3*TINY)
1268 self.identical(fromHex('0x0.ffffffffffffd8p-1022'), MIN-2*TINY)
1269 self.identical(fromHex('0x0.ffffffffffffdap-1022'), MIN-2*TINY)
1270 self.identical(fromHex('0x0.ffffffffffffdcp-1022'), MIN-2*TINY)
1271 self.identical(fromHex('0x0.ffffffffffffdep-1022'), MIN-2*TINY)
1272 self.identical(fromHex('0x0.ffffffffffffe0p-1022'), MIN-2*TINY)
1273 self.identical(fromHex('0x0.ffffffffffffe2p-1022'), MIN-2*TINY)
1274 self.identical(fromHex('0x0.ffffffffffffe4p-1022'), MIN-2*TINY)
1275 self.identical(fromHex('0x0.ffffffffffffe6p-1022'), MIN-2*TINY)
1276 self.identical(fromHex('0x0.ffffffffffffe8p-1022'), MIN-2*TINY)
1277 self.identical(fromHex('0x0.ffffffffffffeap-1022'), MIN-TINY)
1278 self.identical(fromHex('0x0.ffffffffffffecp-1022'), MIN-TINY)
1279 self.identical(fromHex('0x0.ffffffffffffeep-1022'), MIN-TINY)
1280 self.identical(fromHex('0x0.fffffffffffff0p-1022'), MIN-TINY)
1281 self.identical(fromHex('0x0.fffffffffffff2p-1022'), MIN-TINY)
1282 self.identical(fromHex('0x0.fffffffffffff4p-1022'), MIN-TINY)
1283 self.identical(fromHex('0x0.fffffffffffff6p-1022'), MIN-TINY)
1284 self.identical(fromHex('0x0.fffffffffffff8p-1022'), MIN)
1285 self.identical(fromHex('0x0.fffffffffffffap-1022'), MIN)
1286 self.identical(fromHex('0x0.fffffffffffffcp-1022'), MIN)
1287 self.identical(fromHex('0x0.fffffffffffffep-1022'), MIN)
1288 self.identical(fromHex('0x1.00000000000000p-1022'), MIN)
1289 self.identical(fromHex('0x1.00000000000002p-1022'), MIN)
1290 self.identical(fromHex('0x1.00000000000004p-1022'), MIN)
1291 self.identical(fromHex('0x1.00000000000006p-1022'), MIN)
1292 self.identical(fromHex('0x1.00000000000008p-1022'), MIN)
1293 self.identical(fromHex('0x1.0000000000000ap-1022'), MIN+TINY)
1294 self.identical(fromHex('0x1.0000000000000cp-1022'), MIN+TINY)
1295 self.identical(fromHex('0x1.0000000000000ep-1022'), MIN+TINY)
1296 self.identical(fromHex('0x1.00000000000010p-1022'), MIN+TINY)
1297 self.identical(fromHex('0x1.00000000000012p-1022'), MIN+TINY)
1298 self.identical(fromHex('0x1.00000000000014p-1022'), MIN+TINY)
1299 self.identical(fromHex('0x1.00000000000016p-1022'), MIN+TINY)
1300 self.identical(fromHex('0x1.00000000000018p-1022'), MIN+2*TINY)
1301
1302 # ... and near 1.0.
1303 self.identical(fromHex('0x0.fffffffffffff0p0'), 1.0-EPS)
1304 self.identical(fromHex('0x0.fffffffffffff1p0'), 1.0-EPS)
1305 self.identical(fromHex('0X0.fffffffffffff2p0'), 1.0-EPS)
1306 self.identical(fromHex('0x0.fffffffffffff3p0'), 1.0-EPS)
1307 self.identical(fromHex('0X0.fffffffffffff4p0'), 1.0-EPS)
1308 self.identical(fromHex('0X0.fffffffffffff5p0'), 1.0-EPS/2)
1309 self.identical(fromHex('0X0.fffffffffffff6p0'), 1.0-EPS/2)
1310 self.identical(fromHex('0x0.fffffffffffff7p0'), 1.0-EPS/2)
1311 self.identical(fromHex('0x0.fffffffffffff8p0'), 1.0-EPS/2)
1312 self.identical(fromHex('0X0.fffffffffffff9p0'), 1.0-EPS/2)
1313 self.identical(fromHex('0X0.fffffffffffffap0'), 1.0-EPS/2)
1314 self.identical(fromHex('0x0.fffffffffffffbp0'), 1.0-EPS/2)
1315 self.identical(fromHex('0X0.fffffffffffffcp0'), 1.0)
1316 self.identical(fromHex('0x0.fffffffffffffdp0'), 1.0)
1317 self.identical(fromHex('0X0.fffffffffffffep0'), 1.0)
1318 self.identical(fromHex('0x0.ffffffffffffffp0'), 1.0)
1319 self.identical(fromHex('0X1.00000000000000p0'), 1.0)
1320 self.identical(fromHex('0X1.00000000000001p0'), 1.0)
1321 self.identical(fromHex('0x1.00000000000002p0'), 1.0)
1322 self.identical(fromHex('0X1.00000000000003p0'), 1.0)
1323 self.identical(fromHex('0x1.00000000000004p0'), 1.0)
1324 self.identical(fromHex('0X1.00000000000005p0'), 1.0)
1325 self.identical(fromHex('0X1.00000000000006p0'), 1.0)
1326 self.identical(fromHex('0X1.00000000000007p0'), 1.0)
1327 self.identical(fromHex('0x1.00000000000007ffffffffffffffffffffp0'),
1328 1.0)
1329 self.identical(fromHex('0x1.00000000000008p0'), 1.0)
1330 self.identical(fromHex('0x1.00000000000008000000000000000001p0'),
1331 1+EPS)
1332 self.identical(fromHex('0X1.00000000000009p0'), 1.0+EPS)
1333 self.identical(fromHex('0x1.0000000000000ap0'), 1.0+EPS)
1334 self.identical(fromHex('0x1.0000000000000bp0'), 1.0+EPS)
1335 self.identical(fromHex('0X1.0000000000000cp0'), 1.0+EPS)
1336 self.identical(fromHex('0x1.0000000000000dp0'), 1.0+EPS)
1337 self.identical(fromHex('0x1.0000000000000ep0'), 1.0+EPS)
1338 self.identical(fromHex('0X1.0000000000000fp0'), 1.0+EPS)
1339 self.identical(fromHex('0x1.00000000000010p0'), 1.0+EPS)
1340 self.identical(fromHex('0X1.00000000000011p0'), 1.0+EPS)
1341 self.identical(fromHex('0x1.00000000000012p0'), 1.0+EPS)
1342 self.identical(fromHex('0X1.00000000000013p0'), 1.0+EPS)
1343 self.identical(fromHex('0X1.00000000000014p0'), 1.0+EPS)
1344 self.identical(fromHex('0x1.00000000000015p0'), 1.0+EPS)
1345 self.identical(fromHex('0x1.00000000000016p0'), 1.0+EPS)
1346 self.identical(fromHex('0X1.00000000000017p0'), 1.0+EPS)
1347 self.identical(fromHex('0x1.00000000000017ffffffffffffffffffffp0'),
1348 1.0+EPS)
1349 self.identical(fromHex('0x1.00000000000018p0'), 1.0+2*EPS)
1350 self.identical(fromHex('0X1.00000000000018000000000000000001p0'),
1351 1.0+2*EPS)
1352 self.identical(fromHex('0x1.00000000000019p0'), 1.0+2*EPS)
1353 self.identical(fromHex('0X1.0000000000001ap0'), 1.0+2*EPS)
1354 self.identical(fromHex('0X1.0000000000001bp0'), 1.0+2*EPS)
1355 self.identical(fromHex('0x1.0000000000001cp0'), 1.0+2*EPS)
1356 self.identical(fromHex('0x1.0000000000001dp0'), 1.0+2*EPS)
1357 self.identical(fromHex('0x1.0000000000001ep0'), 1.0+2*EPS)
1358 self.identical(fromHex('0X1.0000000000001fp0'), 1.0+2*EPS)
1359 self.identical(fromHex('0x1.00000000000020p0'), 1.0+2*EPS)
1360
1361 def test_roundtrip(self):
1362 def roundtrip(x):
1363 return fromHex(toHex(x))
1364
1365 for x in [NAN, INF, self.MAX, self.MIN, self.MIN-self.TINY, self.TINY, 0.0]:
1366 self.identical(x, roundtrip(x))
1367 self.identical(-x, roundtrip(-x))
1368
1369 # fromHex(toHex(x)) should exactly recover x, for any non-NaN float x.
1370 import random
1371 for i in xrange(10000):
1372 e = random.randrange(-1200, 1200)
1373 m = random.random()
1374 s = random.choice([1.0, -1.0])
1375 try:
1376 x = s*ldexp(m, e)
1377 except OverflowError:
1378 pass
1379 else:
1380 self.identical(x, fromHex(toHex(x)))
1381
Christian Heimes6f341092008-04-18 23:13:07 +00001382
Michael W. Hudsonba283e22005-05-27 15:23:20 +00001383def test_main():
1384 test_support.run_unittest(
Amaury Forgeot d'Arcfeb8cad2008-09-06 20:53:51 +00001385 GeneralFloatCases,
Michael W. Hudsonba283e22005-05-27 15:23:20 +00001386 FormatFunctionsTestCase,
1387 UnknownFormatTestCase,
Christian Heimes284d9272007-12-10 22:28:56 +00001388 IEEEFormatTestCase,
Christian Heimes0a8143f2007-12-18 23:22:54 +00001389 ReprTestCase,
Mark Dickinsonbd15a062009-11-18 19:33:35 +00001390 RoundTestCase,
Christian Heimes0a8143f2007-12-18 23:22:54 +00001391 InfNanTest,
Mark Dickinson7103aa42008-07-15 19:08:33 +00001392 HexFloatTestCase,
Christian Heimesf15c66e2007-12-11 00:54:34 +00001393 )
Michael W. Hudsonba283e22005-05-27 15:23:20 +00001394
1395if __name__ == '__main__':
1396 test_main()