python (3.12.0)
1 import fractions
2 import operator
3 import os
4 import random
5 import sys
6 import struct
7 import time
8 import unittest
9
10 from test import support
11 from test.test_grammar import (VALID_UNDERSCORE_LITERALS,
12 INVALID_UNDERSCORE_LITERALS)
13 from math import isinf, isnan, copysign, ldexp
14 import math
15
16 try:
17 import _testcapi
18 except ImportError:
19 _testcapi = None
20
21 HAVE_IEEE_754 = float.__getformat__("double").startswith("IEEE")
22 INF = float("inf")
23 NAN = float("nan")
24
25
26 #locate file with float format test values
27 test_dir = os.path.dirname(__file__) or os.curdir
28 format_testfile = os.path.join(test_dir, 'formatfloat_testcases.txt')
29
30 class ESC[4;38;5;81mFloatSubclass(ESC[4;38;5;149mfloat):
31 pass
32
33 class ESC[4;38;5;81mOtherFloatSubclass(ESC[4;38;5;149mfloat):
34 pass
35
36 class ESC[4;38;5;81mGeneralFloatCases(ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
37
38 def test_float(self):
39 self.assertEqual(float(3.14), 3.14)
40 self.assertEqual(float(314), 314.0)
41 self.assertEqual(float(" 3.14 "), 3.14)
42 self.assertRaises(ValueError, float, " 0x3.1 ")
43 self.assertRaises(ValueError, float, " -0x3.p-1 ")
44 self.assertRaises(ValueError, float, " +0x3.p-1 ")
45 self.assertRaises(ValueError, float, "++3.14")
46 self.assertRaises(ValueError, float, "+-3.14")
47 self.assertRaises(ValueError, float, "-+3.14")
48 self.assertRaises(ValueError, float, "--3.14")
49 self.assertRaises(ValueError, float, ".nan")
50 self.assertRaises(ValueError, float, "+.inf")
51 self.assertRaises(ValueError, float, ".")
52 self.assertRaises(ValueError, float, "-.")
53 self.assertRaises(TypeError, float, {})
54 self.assertRaisesRegex(TypeError, "not 'dict'", float, {})
55 # Lone surrogate
56 self.assertRaises(ValueError, float, '\uD8F0')
57 # check that we don't accept alternate exponent markers
58 self.assertRaises(ValueError, float, "-1.7d29")
59 self.assertRaises(ValueError, float, "3D-14")
60 self.assertEqual(float(" \u0663.\u0661\u0664 "), 3.14)
61 self.assertEqual(float("\N{EM SPACE}3.14\N{EN SPACE}"), 3.14)
62 # extra long strings should not be a problem
63 float(b'.' + b'1'*1000)
64 float('.' + '1'*1000)
65 # Invalid unicode string
66 # See bpo-34087
67 self.assertRaises(ValueError, float, '\u3053\u3093\u306b\u3061\u306f')
68
69 def test_noargs(self):
70 self.assertEqual(float(), 0.0)
71
72 def test_underscores(self):
73 for lit in VALID_UNDERSCORE_LITERALS:
74 if not any(ch in lit for ch in 'jJxXoObB'):
75 self.assertEqual(float(lit), eval(lit))
76 self.assertEqual(float(lit), float(lit.replace('_', '')))
77 for lit in INVALID_UNDERSCORE_LITERALS:
78 if lit in ('0_7', '09_99'): # octals are not recognized here
79 continue
80 if not any(ch in lit for ch in 'jJxXoObB'):
81 self.assertRaises(ValueError, float, lit)
82 # Additional test cases; nan and inf are never valid as literals,
83 # only in the float() constructor, but we don't allow underscores
84 # in or around them.
85 self.assertRaises(ValueError, float, '_NaN')
86 self.assertRaises(ValueError, float, 'Na_N')
87 self.assertRaises(ValueError, float, 'IN_F')
88 self.assertRaises(ValueError, float, '-_INF')
89 self.assertRaises(ValueError, float, '-INF_')
90 # Check that we handle bytes values correctly.
91 self.assertRaises(ValueError, float, b'0_.\xff9')
92
93 def test_non_numeric_input_types(self):
94 # Test possible non-numeric types for the argument x, including
95 # subclasses of the explicitly documented accepted types.
96 class ESC[4;38;5;81mCustomStr(ESC[4;38;5;149mstr): pass
97 class ESC[4;38;5;81mCustomBytes(ESC[4;38;5;149mbytes): pass
98 class ESC[4;38;5;81mCustomByteArray(ESC[4;38;5;149mbytearray): pass
99
100 factories = [
101 bytes,
102 bytearray,
103 lambda b: CustomStr(b.decode()),
104 CustomBytes,
105 CustomByteArray,
106 memoryview,
107 ]
108 try:
109 from array import array
110 except ImportError:
111 pass
112 else:
113 factories.append(lambda b: array('B', b))
114
115 for f in factories:
116 x = f(b" 3.14 ")
117 with self.subTest(type(x)):
118 self.assertEqual(float(x), 3.14)
119 with self.assertRaisesRegex(ValueError, "could not convert"):
120 float(f(b'A' * 0x10))
121
122 def test_float_memoryview(self):
123 self.assertEqual(float(memoryview(b'12.3')[1:4]), 2.3)
124 self.assertEqual(float(memoryview(b'12.3\x00')[1:4]), 2.3)
125 self.assertEqual(float(memoryview(b'12.3 ')[1:4]), 2.3)
126 self.assertEqual(float(memoryview(b'12.3A')[1:4]), 2.3)
127 self.assertEqual(float(memoryview(b'12.34')[1:4]), 2.3)
128
129 def test_error_message(self):
130 def check(s):
131 with self.assertRaises(ValueError, msg='float(%r)' % (s,)) as cm:
132 float(s)
133 self.assertEqual(str(cm.exception),
134 'could not convert string to float: %r' % (s,))
135
136 check('\xbd')
137 check('123\xbd')
138 check(' 123 456 ')
139 check(b' 123 456 ')
140 # all whitespace (cf. https://github.com/python/cpython/issues/95605)
141 check('')
142 check(' ')
143 check('\t \n')
144
145 # non-ascii digits (error came from non-digit '!')
146 check('\u0663\u0661\u0664!')
147 # embedded NUL
148 check('123\x00')
149 check('123\x00 245')
150 check('123\x00245')
151 # byte string with embedded NUL
152 check(b'123\x00')
153 # non-UTF-8 byte string
154 check(b'123\xa0')
155
156 @support.run_with_locale('LC_NUMERIC', 'fr_FR', 'de_DE')
157 def test_float_with_comma(self):
158 # set locale to something that doesn't use '.' for the decimal point
159 # float must not accept the locale specific decimal point but
160 # it still has to accept the normal python syntax
161 import locale
162 if not locale.localeconv()['decimal_point'] == ',':
163 self.skipTest('decimal_point is not ","')
164
165 self.assertEqual(float(" 3.14 "), 3.14)
166 self.assertEqual(float("+3.14 "), 3.14)
167 self.assertEqual(float("-3.14 "), -3.14)
168 self.assertEqual(float(".14 "), .14)
169 self.assertEqual(float("3. "), 3.0)
170 self.assertEqual(float("3.e3 "), 3000.0)
171 self.assertEqual(float("3.2e3 "), 3200.0)
172 self.assertEqual(float("2.5e-1 "), 0.25)
173 self.assertEqual(float("5e-1"), 0.5)
174 self.assertRaises(ValueError, float, " 3,14 ")
175 self.assertRaises(ValueError, float, " +3,14 ")
176 self.assertRaises(ValueError, float, " -3,14 ")
177 self.assertRaises(ValueError, float, " 0x3.1 ")
178 self.assertRaises(ValueError, float, " -0x3.p-1 ")
179 self.assertRaises(ValueError, float, " +0x3.p-1 ")
180 self.assertEqual(float(" 25.e-1 "), 2.5)
181 self.assertAlmostEqual(float(" .25e-1 "), .025)
182
183 def test_floatconversion(self):
184 # Make sure that calls to __float__() work properly
185 class ESC[4;38;5;81mFoo1(ESC[4;38;5;149mobject):
186 def __float__(self):
187 return 42.
188
189 class ESC[4;38;5;81mFoo2(ESC[4;38;5;149mfloat):
190 def __float__(self):
191 return 42.
192
193 class ESC[4;38;5;81mFoo3(ESC[4;38;5;149mfloat):
194 def __new__(cls, value=0.):
195 return float.__new__(cls, 2*value)
196
197 def __float__(self):
198 return self
199
200 class ESC[4;38;5;81mFoo4(ESC[4;38;5;149mfloat):
201 def __float__(self):
202 return 42
203
204 # Issue 5759: __float__ not called on str subclasses (though it is on
205 # unicode subclasses).
206 class ESC[4;38;5;81mFooStr(ESC[4;38;5;149mstr):
207 def __float__(self):
208 return float(str(self)) + 1
209
210 self.assertEqual(float(Foo1()), 42.)
211 self.assertEqual(float(Foo2()), 42.)
212 with self.assertWarns(DeprecationWarning):
213 self.assertEqual(float(Foo3(21)), 42.)
214 self.assertRaises(TypeError, float, Foo4(42))
215 self.assertEqual(float(FooStr('8')), 9.)
216
217 class ESC[4;38;5;81mFoo5:
218 def __float__(self):
219 return ""
220 self.assertRaises(TypeError, time.sleep, Foo5())
221
222 # Issue #24731
223 class ESC[4;38;5;81mF:
224 def __float__(self):
225 return OtherFloatSubclass(42.)
226 with self.assertWarns(DeprecationWarning):
227 self.assertEqual(float(F()), 42.)
228 with self.assertWarns(DeprecationWarning):
229 self.assertIs(type(float(F())), float)
230 with self.assertWarns(DeprecationWarning):
231 self.assertEqual(FloatSubclass(F()), 42.)
232 with self.assertWarns(DeprecationWarning):
233 self.assertIs(type(FloatSubclass(F())), FloatSubclass)
234
235 class ESC[4;38;5;81mMyIndex:
236 def __init__(self, value):
237 self.value = value
238 def __index__(self):
239 return self.value
240
241 self.assertEqual(float(MyIndex(42)), 42.0)
242 self.assertRaises(OverflowError, float, MyIndex(2**2000))
243
244 class ESC[4;38;5;81mMyInt:
245 def __int__(self):
246 return 42
247
248 self.assertRaises(TypeError, float, MyInt())
249
250 def test_keyword_args(self):
251 with self.assertRaisesRegex(TypeError, 'keyword argument'):
252 float(x='3.14')
253
254 def test_keywords_in_subclass(self):
255 class ESC[4;38;5;81msubclass(ESC[4;38;5;149mfloat):
256 pass
257 u = subclass(2.5)
258 self.assertIs(type(u), subclass)
259 self.assertEqual(float(u), 2.5)
260 with self.assertRaises(TypeError):
261 subclass(x=0)
262
263 class ESC[4;38;5;81msubclass_with_init(ESC[4;38;5;149mfloat):
264 def __init__(self, arg, newarg=None):
265 self.newarg = newarg
266 u = subclass_with_init(2.5, newarg=3)
267 self.assertIs(type(u), subclass_with_init)
268 self.assertEqual(float(u), 2.5)
269 self.assertEqual(u.newarg, 3)
270
271 class ESC[4;38;5;81msubclass_with_new(ESC[4;38;5;149mfloat):
272 def __new__(cls, arg, newarg=None):
273 self = super().__new__(cls, arg)
274 self.newarg = newarg
275 return self
276 u = subclass_with_new(2.5, newarg=3)
277 self.assertIs(type(u), subclass_with_new)
278 self.assertEqual(float(u), 2.5)
279 self.assertEqual(u.newarg, 3)
280
281 def test_is_integer(self):
282 self.assertFalse((1.1).is_integer())
283 self.assertTrue((1.).is_integer())
284 self.assertFalse(float("nan").is_integer())
285 self.assertFalse(float("inf").is_integer())
286
287 def test_floatasratio(self):
288 for f, ratio in [
289 (0.875, (7, 8)),
290 (-0.875, (-7, 8)),
291 (0.0, (0, 1)),
292 (11.5, (23, 2)),
293 ]:
294 self.assertEqual(f.as_integer_ratio(), ratio)
295
296 for i in range(10000):
297 f = random.random()
298 f *= 10 ** random.randint(-100, 100)
299 n, d = f.as_integer_ratio()
300 self.assertEqual(float(n).__truediv__(d), f)
301
302 R = fractions.Fraction
303 self.assertEqual(R(0, 1),
304 R(*float(0.0).as_integer_ratio()))
305 self.assertEqual(R(5, 2),
306 R(*float(2.5).as_integer_ratio()))
307 self.assertEqual(R(1, 2),
308 R(*float(0.5).as_integer_ratio()))
309 self.assertEqual(R(4728779608739021, 2251799813685248),
310 R(*float(2.1).as_integer_ratio()))
311 self.assertEqual(R(-4728779608739021, 2251799813685248),
312 R(*float(-2.1).as_integer_ratio()))
313 self.assertEqual(R(-2100, 1),
314 R(*float(-2100.0).as_integer_ratio()))
315
316 self.assertRaises(OverflowError, float('inf').as_integer_ratio)
317 self.assertRaises(OverflowError, float('-inf').as_integer_ratio)
318 self.assertRaises(ValueError, float('nan').as_integer_ratio)
319
320 def test_float_containment(self):
321 floats = (INF, -INF, 0.0, 1.0, NAN)
322 for f in floats:
323 self.assertIn(f, [f])
324 self.assertIn(f, (f,))
325 self.assertIn(f, {f})
326 self.assertIn(f, {f: None})
327 self.assertEqual([f].count(f), 1, "[].count('%r') != 1" % f)
328 self.assertIn(f, floats)
329
330 for f in floats:
331 # nonidentical containers, same type, same contents
332 self.assertTrue([f] == [f], "[%r] != [%r]" % (f, f))
333 self.assertTrue((f,) == (f,), "(%r,) != (%r,)" % (f, f))
334 self.assertTrue({f} == {f}, "{%r} != {%r}" % (f, f))
335 self.assertTrue({f : None} == {f: None}, "{%r : None} != "
336 "{%r : None}" % (f, f))
337
338 # identical containers
339 l, t, s, d = [f], (f,), {f}, {f: None}
340 self.assertTrue(l == l, "[%r] not equal to itself" % f)
341 self.assertTrue(t == t, "(%r,) not equal to itself" % f)
342 self.assertTrue(s == s, "{%r} not equal to itself" % f)
343 self.assertTrue(d == d, "{%r : None} not equal to itself" % f)
344
345 def assertEqualAndEqualSign(self, a, b):
346 # fail unless a == b and a and b have the same sign bit;
347 # the only difference from assertEqual is that this test
348 # distinguishes -0.0 and 0.0.
349 self.assertEqual((a, copysign(1.0, a)), (b, copysign(1.0, b)))
350
351 def test_float_floor(self):
352 self.assertIsInstance(float(0.5).__floor__(), int)
353 self.assertEqual(float(0.5).__floor__(), 0)
354 self.assertEqual(float(1.0).__floor__(), 1)
355 self.assertEqual(float(1.5).__floor__(), 1)
356 self.assertEqual(float(-0.5).__floor__(), -1)
357 self.assertEqual(float(-1.0).__floor__(), -1)
358 self.assertEqual(float(-1.5).__floor__(), -2)
359 self.assertEqual(float(1.23e167).__floor__(), 1.23e167)
360 self.assertEqual(float(-1.23e167).__floor__(), -1.23e167)
361 self.assertRaises(ValueError, float("nan").__floor__)
362 self.assertRaises(OverflowError, float("inf").__floor__)
363 self.assertRaises(OverflowError, float("-inf").__floor__)
364
365 def test_float_ceil(self):
366 self.assertIsInstance(float(0.5).__ceil__(), int)
367 self.assertEqual(float(0.5).__ceil__(), 1)
368 self.assertEqual(float(1.0).__ceil__(), 1)
369 self.assertEqual(float(1.5).__ceil__(), 2)
370 self.assertEqual(float(-0.5).__ceil__(), 0)
371 self.assertEqual(float(-1.0).__ceil__(), -1)
372 self.assertEqual(float(-1.5).__ceil__(), -1)
373 self.assertEqual(float(1.23e167).__ceil__(), 1.23e167)
374 self.assertEqual(float(-1.23e167).__ceil__(), -1.23e167)
375 self.assertRaises(ValueError, float("nan").__ceil__)
376 self.assertRaises(OverflowError, float("inf").__ceil__)
377 self.assertRaises(OverflowError, float("-inf").__ceil__)
378
379 @support.requires_IEEE_754
380 def test_float_mod(self):
381 # Check behaviour of % operator for IEEE 754 special cases.
382 # In particular, check signs of zeros.
383 mod = operator.mod
384
385 self.assertEqualAndEqualSign(mod(-1.0, 1.0), 0.0)
386 self.assertEqualAndEqualSign(mod(-1e-100, 1.0), 1.0)
387 self.assertEqualAndEqualSign(mod(-0.0, 1.0), 0.0)
388 self.assertEqualAndEqualSign(mod(0.0, 1.0), 0.0)
389 self.assertEqualAndEqualSign(mod(1e-100, 1.0), 1e-100)
390 self.assertEqualAndEqualSign(mod(1.0, 1.0), 0.0)
391
392 self.assertEqualAndEqualSign(mod(-1.0, -1.0), -0.0)
393 self.assertEqualAndEqualSign(mod(-1e-100, -1.0), -1e-100)
394 self.assertEqualAndEqualSign(mod(-0.0, -1.0), -0.0)
395 self.assertEqualAndEqualSign(mod(0.0, -1.0), -0.0)
396 self.assertEqualAndEqualSign(mod(1e-100, -1.0), -1.0)
397 self.assertEqualAndEqualSign(mod(1.0, -1.0), -0.0)
398
399 @support.requires_IEEE_754
400 def test_float_pow(self):
401 # test builtin pow and ** operator for IEEE 754 special cases.
402 # Special cases taken from section F.9.4.4 of the C99 specification
403
404 for pow_op in pow, operator.pow:
405 # x**NAN is NAN for any x except 1
406 self.assertTrue(isnan(pow_op(-INF, NAN)))
407 self.assertTrue(isnan(pow_op(-2.0, NAN)))
408 self.assertTrue(isnan(pow_op(-1.0, NAN)))
409 self.assertTrue(isnan(pow_op(-0.5, NAN)))
410 self.assertTrue(isnan(pow_op(-0.0, NAN)))
411 self.assertTrue(isnan(pow_op(0.0, NAN)))
412 self.assertTrue(isnan(pow_op(0.5, NAN)))
413 self.assertTrue(isnan(pow_op(2.0, NAN)))
414 self.assertTrue(isnan(pow_op(INF, NAN)))
415 self.assertTrue(isnan(pow_op(NAN, NAN)))
416
417 # NAN**y is NAN for any y except +-0
418 self.assertTrue(isnan(pow_op(NAN, -INF)))
419 self.assertTrue(isnan(pow_op(NAN, -2.0)))
420 self.assertTrue(isnan(pow_op(NAN, -1.0)))
421 self.assertTrue(isnan(pow_op(NAN, -0.5)))
422 self.assertTrue(isnan(pow_op(NAN, 0.5)))
423 self.assertTrue(isnan(pow_op(NAN, 1.0)))
424 self.assertTrue(isnan(pow_op(NAN, 2.0)))
425 self.assertTrue(isnan(pow_op(NAN, INF)))
426
427 # (+-0)**y raises ZeroDivisionError for y a negative odd integer
428 self.assertRaises(ZeroDivisionError, pow_op, -0.0, -1.0)
429 self.assertRaises(ZeroDivisionError, pow_op, 0.0, -1.0)
430
431 # (+-0)**y raises ZeroDivisionError for y finite and negative
432 # but not an odd integer
433 self.assertRaises(ZeroDivisionError, pow_op, -0.0, -2.0)
434 self.assertRaises(ZeroDivisionError, pow_op, -0.0, -0.5)
435 self.assertRaises(ZeroDivisionError, pow_op, 0.0, -2.0)
436 self.assertRaises(ZeroDivisionError, pow_op, 0.0, -0.5)
437
438 # (+-0)**y is +-0 for y a positive odd integer
439 self.assertEqualAndEqualSign(pow_op(-0.0, 1.0), -0.0)
440 self.assertEqualAndEqualSign(pow_op(0.0, 1.0), 0.0)
441
442 # (+-0)**y is 0 for y finite and positive but not an odd integer
443 self.assertEqualAndEqualSign(pow_op(-0.0, 0.5), 0.0)
444 self.assertEqualAndEqualSign(pow_op(-0.0, 2.0), 0.0)
445 self.assertEqualAndEqualSign(pow_op(0.0, 0.5), 0.0)
446 self.assertEqualAndEqualSign(pow_op(0.0, 2.0), 0.0)
447
448 # (-1)**+-inf is 1
449 self.assertEqualAndEqualSign(pow_op(-1.0, -INF), 1.0)
450 self.assertEqualAndEqualSign(pow_op(-1.0, INF), 1.0)
451
452 # 1**y is 1 for any y, even if y is an infinity or nan
453 self.assertEqualAndEqualSign(pow_op(1.0, -INF), 1.0)
454 self.assertEqualAndEqualSign(pow_op(1.0, -2.0), 1.0)
455 self.assertEqualAndEqualSign(pow_op(1.0, -1.0), 1.0)
456 self.assertEqualAndEqualSign(pow_op(1.0, -0.5), 1.0)
457 self.assertEqualAndEqualSign(pow_op(1.0, -0.0), 1.0)
458 self.assertEqualAndEqualSign(pow_op(1.0, 0.0), 1.0)
459 self.assertEqualAndEqualSign(pow_op(1.0, 0.5), 1.0)
460 self.assertEqualAndEqualSign(pow_op(1.0, 1.0), 1.0)
461 self.assertEqualAndEqualSign(pow_op(1.0, 2.0), 1.0)
462 self.assertEqualAndEqualSign(pow_op(1.0, INF), 1.0)
463 self.assertEqualAndEqualSign(pow_op(1.0, NAN), 1.0)
464
465 # x**+-0 is 1 for any x, even if x is a zero, infinity, or nan
466 self.assertEqualAndEqualSign(pow_op(-INF, 0.0), 1.0)
467 self.assertEqualAndEqualSign(pow_op(-2.0, 0.0), 1.0)
468 self.assertEqualAndEqualSign(pow_op(-1.0, 0.0), 1.0)
469 self.assertEqualAndEqualSign(pow_op(-0.5, 0.0), 1.0)
470 self.assertEqualAndEqualSign(pow_op(-0.0, 0.0), 1.0)
471 self.assertEqualAndEqualSign(pow_op(0.0, 0.0), 1.0)
472 self.assertEqualAndEqualSign(pow_op(0.5, 0.0), 1.0)
473 self.assertEqualAndEqualSign(pow_op(1.0, 0.0), 1.0)
474 self.assertEqualAndEqualSign(pow_op(2.0, 0.0), 1.0)
475 self.assertEqualAndEqualSign(pow_op(INF, 0.0), 1.0)
476 self.assertEqualAndEqualSign(pow_op(NAN, 0.0), 1.0)
477 self.assertEqualAndEqualSign(pow_op(-INF, -0.0), 1.0)
478 self.assertEqualAndEqualSign(pow_op(-2.0, -0.0), 1.0)
479 self.assertEqualAndEqualSign(pow_op(-1.0, -0.0), 1.0)
480 self.assertEqualAndEqualSign(pow_op(-0.5, -0.0), 1.0)
481 self.assertEqualAndEqualSign(pow_op(-0.0, -0.0), 1.0)
482 self.assertEqualAndEqualSign(pow_op(0.0, -0.0), 1.0)
483 self.assertEqualAndEqualSign(pow_op(0.5, -0.0), 1.0)
484 self.assertEqualAndEqualSign(pow_op(1.0, -0.0), 1.0)
485 self.assertEqualAndEqualSign(pow_op(2.0, -0.0), 1.0)
486 self.assertEqualAndEqualSign(pow_op(INF, -0.0), 1.0)
487 self.assertEqualAndEqualSign(pow_op(NAN, -0.0), 1.0)
488
489 # x**y defers to complex pow for finite negative x and
490 # non-integral y.
491 self.assertEqual(type(pow_op(-2.0, -0.5)), complex)
492 self.assertEqual(type(pow_op(-2.0, 0.5)), complex)
493 self.assertEqual(type(pow_op(-1.0, -0.5)), complex)
494 self.assertEqual(type(pow_op(-1.0, 0.5)), complex)
495 self.assertEqual(type(pow_op(-0.5, -0.5)), complex)
496 self.assertEqual(type(pow_op(-0.5, 0.5)), complex)
497
498 # x**-INF is INF for abs(x) < 1
499 self.assertEqualAndEqualSign(pow_op(-0.5, -INF), INF)
500 self.assertEqualAndEqualSign(pow_op(-0.0, -INF), INF)
501 self.assertEqualAndEqualSign(pow_op(0.0, -INF), INF)
502 self.assertEqualAndEqualSign(pow_op(0.5, -INF), INF)
503
504 # x**-INF is 0 for abs(x) > 1
505 self.assertEqualAndEqualSign(pow_op(-INF, -INF), 0.0)
506 self.assertEqualAndEqualSign(pow_op(-2.0, -INF), 0.0)
507 self.assertEqualAndEqualSign(pow_op(2.0, -INF), 0.0)
508 self.assertEqualAndEqualSign(pow_op(INF, -INF), 0.0)
509
510 # x**INF is 0 for abs(x) < 1
511 self.assertEqualAndEqualSign(pow_op(-0.5, INF), 0.0)
512 self.assertEqualAndEqualSign(pow_op(-0.0, INF), 0.0)
513 self.assertEqualAndEqualSign(pow_op(0.0, INF), 0.0)
514 self.assertEqualAndEqualSign(pow_op(0.5, INF), 0.0)
515
516 # x**INF is INF for abs(x) > 1
517 self.assertEqualAndEqualSign(pow_op(-INF, INF), INF)
518 self.assertEqualAndEqualSign(pow_op(-2.0, INF), INF)
519 self.assertEqualAndEqualSign(pow_op(2.0, INF), INF)
520 self.assertEqualAndEqualSign(pow_op(INF, INF), INF)
521
522 # (-INF)**y is -0.0 for y a negative odd integer
523 self.assertEqualAndEqualSign(pow_op(-INF, -1.0), -0.0)
524
525 # (-INF)**y is 0.0 for y negative but not an odd integer
526 self.assertEqualAndEqualSign(pow_op(-INF, -0.5), 0.0)
527 self.assertEqualAndEqualSign(pow_op(-INF, -2.0), 0.0)
528
529 # (-INF)**y is -INF for y a positive odd integer
530 self.assertEqualAndEqualSign(pow_op(-INF, 1.0), -INF)
531
532 # (-INF)**y is INF for y positive but not an odd integer
533 self.assertEqualAndEqualSign(pow_op(-INF, 0.5), INF)
534 self.assertEqualAndEqualSign(pow_op(-INF, 2.0), INF)
535
536 # INF**y is INF for y positive
537 self.assertEqualAndEqualSign(pow_op(INF, 0.5), INF)
538 self.assertEqualAndEqualSign(pow_op(INF, 1.0), INF)
539 self.assertEqualAndEqualSign(pow_op(INF, 2.0), INF)
540
541 # INF**y is 0.0 for y negative
542 self.assertEqualAndEqualSign(pow_op(INF, -2.0), 0.0)
543 self.assertEqualAndEqualSign(pow_op(INF, -1.0), 0.0)
544 self.assertEqualAndEqualSign(pow_op(INF, -0.5), 0.0)
545
546 # basic checks not covered by the special cases above
547 self.assertEqualAndEqualSign(pow_op(-2.0, -2.0), 0.25)
548 self.assertEqualAndEqualSign(pow_op(-2.0, -1.0), -0.5)
549 self.assertEqualAndEqualSign(pow_op(-2.0, -0.0), 1.0)
550 self.assertEqualAndEqualSign(pow_op(-2.0, 0.0), 1.0)
551 self.assertEqualAndEqualSign(pow_op(-2.0, 1.0), -2.0)
552 self.assertEqualAndEqualSign(pow_op(-2.0, 2.0), 4.0)
553 self.assertEqualAndEqualSign(pow_op(-1.0, -2.0), 1.0)
554 self.assertEqualAndEqualSign(pow_op(-1.0, -1.0), -1.0)
555 self.assertEqualAndEqualSign(pow_op(-1.0, -0.0), 1.0)
556 self.assertEqualAndEqualSign(pow_op(-1.0, 0.0), 1.0)
557 self.assertEqualAndEqualSign(pow_op(-1.0, 1.0), -1.0)
558 self.assertEqualAndEqualSign(pow_op(-1.0, 2.0), 1.0)
559 self.assertEqualAndEqualSign(pow_op(2.0, -2.0), 0.25)
560 self.assertEqualAndEqualSign(pow_op(2.0, -1.0), 0.5)
561 self.assertEqualAndEqualSign(pow_op(2.0, -0.0), 1.0)
562 self.assertEqualAndEqualSign(pow_op(2.0, 0.0), 1.0)
563 self.assertEqualAndEqualSign(pow_op(2.0, 1.0), 2.0)
564 self.assertEqualAndEqualSign(pow_op(2.0, 2.0), 4.0)
565
566 # 1 ** large and -1 ** large; some libms apparently
567 # have problems with these
568 self.assertEqualAndEqualSign(pow_op(1.0, -1e100), 1.0)
569 self.assertEqualAndEqualSign(pow_op(1.0, 1e100), 1.0)
570 self.assertEqualAndEqualSign(pow_op(-1.0, -1e100), 1.0)
571 self.assertEqualAndEqualSign(pow_op(-1.0, 1e100), 1.0)
572
573 # check sign for results that underflow to 0
574 self.assertEqualAndEqualSign(pow_op(-2.0, -2000.0), 0.0)
575 self.assertEqual(type(pow_op(-2.0, -2000.5)), complex)
576 self.assertEqualAndEqualSign(pow_op(-2.0, -2001.0), -0.0)
577 self.assertEqualAndEqualSign(pow_op(2.0, -2000.0), 0.0)
578 self.assertEqualAndEqualSign(pow_op(2.0, -2000.5), 0.0)
579 self.assertEqualAndEqualSign(pow_op(2.0, -2001.0), 0.0)
580 self.assertEqualAndEqualSign(pow_op(-0.5, 2000.0), 0.0)
581 self.assertEqual(type(pow_op(-0.5, 2000.5)), complex)
582 self.assertEqualAndEqualSign(pow_op(-0.5, 2001.0), -0.0)
583 self.assertEqualAndEqualSign(pow_op(0.5, 2000.0), 0.0)
584 self.assertEqualAndEqualSign(pow_op(0.5, 2000.5), 0.0)
585 self.assertEqualAndEqualSign(pow_op(0.5, 2001.0), 0.0)
586
587 # check we don't raise an exception for subnormal results,
588 # and validate signs. Tests currently disabled, since
589 # they fail on systems where a subnormal result from pow
590 # is flushed to zero (e.g. Debian/ia64.)
591 #self.assertTrue(0.0 < pow_op(0.5, 1048) < 1e-315)
592 #self.assertTrue(0.0 < pow_op(-0.5, 1048) < 1e-315)
593 #self.assertTrue(0.0 < pow_op(0.5, 1047) < 1e-315)
594 #self.assertTrue(0.0 > pow_op(-0.5, 1047) > -1e-315)
595 #self.assertTrue(0.0 < pow_op(2.0, -1048) < 1e-315)
596 #self.assertTrue(0.0 < pow_op(-2.0, -1048) < 1e-315)
597 #self.assertTrue(0.0 < pow_op(2.0, -1047) < 1e-315)
598 #self.assertTrue(0.0 > pow_op(-2.0, -1047) > -1e-315)
599
600 def test_hash(self):
601 for x in range(-30, 30):
602 self.assertEqual(hash(float(x)), hash(x))
603 self.assertEqual(hash(float(sys.float_info.max)),
604 hash(int(sys.float_info.max)))
605 self.assertEqual(hash(float('inf')), sys.hash_info.inf)
606 self.assertEqual(hash(float('-inf')), -sys.hash_info.inf)
607
608 def test_hash_nan(self):
609 value = float('nan')
610 self.assertEqual(hash(value), object.__hash__(value))
611 class ESC[4;38;5;81mH:
612 def __hash__(self):
613 return 42
614 class ESC[4;38;5;81mF(ESC[4;38;5;149mfloat, ESC[4;38;5;149mH):
615 pass
616 value = F('nan')
617 self.assertEqual(hash(value), object.__hash__(value))
618
619
620 @unittest.skipUnless(hasattr(float, "__getformat__"), "requires __getformat__")
621 class ESC[4;38;5;81mFormatFunctionsTestCase(ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
622 def test_getformat(self):
623 self.assertIn(float.__getformat__('double'),
624 ['unknown', 'IEEE, big-endian', 'IEEE, little-endian'])
625 self.assertIn(float.__getformat__('float'),
626 ['unknown', 'IEEE, big-endian', 'IEEE, little-endian'])
627 self.assertRaises(ValueError, float.__getformat__, 'chicken')
628 self.assertRaises(TypeError, float.__getformat__, 1)
629
630
631 BE_DOUBLE_INF = b'\x7f\xf0\x00\x00\x00\x00\x00\x00'
632 LE_DOUBLE_INF = bytes(reversed(BE_DOUBLE_INF))
633 BE_DOUBLE_NAN = b'\x7f\xf8\x00\x00\x00\x00\x00\x00'
634 LE_DOUBLE_NAN = bytes(reversed(BE_DOUBLE_NAN))
635
636 BE_FLOAT_INF = b'\x7f\x80\x00\x00'
637 LE_FLOAT_INF = bytes(reversed(BE_FLOAT_INF))
638 BE_FLOAT_NAN = b'\x7f\xc0\x00\x00'
639 LE_FLOAT_NAN = bytes(reversed(BE_FLOAT_NAN))
640
641 # on an IEEE platform, all we guarantee is that bit patterns
642 # representing infinities or NaNs do not raise an exception; all else
643 # is accident (today).
644 # let's also try to guarantee that -0.0 and 0.0 don't get confused.
645
646 class ESC[4;38;5;81mIEEEFormatTestCase(ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
647
648 @support.requires_IEEE_754
649 def test_double_specials_do_unpack(self):
650 for fmt, data in [('>d', BE_DOUBLE_INF),
651 ('>d', BE_DOUBLE_NAN),
652 ('<d', LE_DOUBLE_INF),
653 ('<d', LE_DOUBLE_NAN)]:
654 struct.unpack(fmt, data)
655
656 @support.requires_IEEE_754
657 def test_float_specials_do_unpack(self):
658 for fmt, data in [('>f', BE_FLOAT_INF),
659 ('>f', BE_FLOAT_NAN),
660 ('<f', LE_FLOAT_INF),
661 ('<f', LE_FLOAT_NAN)]:
662 struct.unpack(fmt, data)
663
664 @support.requires_IEEE_754
665 @unittest.skipIf(_testcapi is None, 'needs _testcapi')
666 def test_serialized_float_rounding(self):
667 FLT_MAX = _testcapi.FLT_MAX
668 self.assertEqual(struct.pack("<f", 3.40282356e38), struct.pack("<f", FLT_MAX))
669 self.assertEqual(struct.pack("<f", -3.40282356e38), struct.pack("<f", -FLT_MAX))
670
671 class ESC[4;38;5;81mFormatTestCase(ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
672
673 def test_format(self):
674 # these should be rewritten to use both format(x, spec) and
675 # x.__format__(spec)
676
677 self.assertEqual(format(0.0, 'f'), '0.000000')
678
679 # the default is 'g', except for empty format spec
680 self.assertEqual(format(0.0, ''), '0.0')
681 self.assertEqual(format(0.01, ''), '0.01')
682 self.assertEqual(format(0.01, 'g'), '0.01')
683
684 # empty presentation type should format in the same way as str
685 # (issue 5920)
686 x = 100/7.
687 self.assertEqual(format(x, ''), str(x))
688 self.assertEqual(format(x, '-'), str(x))
689 self.assertEqual(format(x, '>'), str(x))
690 self.assertEqual(format(x, '2'), str(x))
691
692 self.assertEqual(format(1.0, 'f'), '1.000000')
693
694 self.assertEqual(format(-1.0, 'f'), '-1.000000')
695
696 self.assertEqual(format( 1.0, ' f'), ' 1.000000')
697 self.assertEqual(format(-1.0, ' f'), '-1.000000')
698 self.assertEqual(format( 1.0, '+f'), '+1.000000')
699 self.assertEqual(format(-1.0, '+f'), '-1.000000')
700
701 # % formatting
702 self.assertEqual(format(-1.0, '%'), '-100.000000%')
703
704 # conversion to string should fail
705 self.assertRaises(ValueError, format, 3.0, "s")
706
707 # confirm format options expected to fail on floats, such as integer
708 # presentation types
709 for format_spec in 'sbcdoxX':
710 self.assertRaises(ValueError, format, 0.0, format_spec)
711 self.assertRaises(ValueError, format, 1.0, format_spec)
712 self.assertRaises(ValueError, format, -1.0, format_spec)
713 self.assertRaises(ValueError, format, 1e100, format_spec)
714 self.assertRaises(ValueError, format, -1e100, format_spec)
715 self.assertRaises(ValueError, format, 1e-100, format_spec)
716 self.assertRaises(ValueError, format, -1e-100, format_spec)
717
718 # issue 3382
719 self.assertEqual(format(NAN, 'f'), 'nan')
720 self.assertEqual(format(NAN, 'F'), 'NAN')
721 self.assertEqual(format(INF, 'f'), 'inf')
722 self.assertEqual(format(INF, 'F'), 'INF')
723
724 @support.requires_IEEE_754
725 def test_format_testfile(self):
726 with open(format_testfile, encoding="utf-8") as testfile:
727 for line in testfile:
728 if line.startswith('--'):
729 continue
730 line = line.strip()
731 if not line:
732 continue
733
734 lhs, rhs = map(str.strip, line.split('->'))
735 fmt, arg = lhs.split()
736 self.assertEqual(fmt % float(arg), rhs)
737 self.assertEqual(fmt % -float(arg), '-' + rhs)
738
739 def test_issue5864(self):
740 self.assertEqual(format(123.456, '.4'), '123.5')
741 self.assertEqual(format(1234.56, '.4'), '1.235e+03')
742 self.assertEqual(format(12345.6, '.4'), '1.235e+04')
743
744 def test_issue35560(self):
745 self.assertEqual(format(123.0, '00'), '123.0')
746 self.assertEqual(format(123.34, '00f'), '123.340000')
747 self.assertEqual(format(123.34, '00e'), '1.233400e+02')
748 self.assertEqual(format(123.34, '00g'), '123.34')
749 self.assertEqual(format(123.34, '00.10f'), '123.3400000000')
750 self.assertEqual(format(123.34, '00.10e'), '1.2334000000e+02')
751 self.assertEqual(format(123.34, '00.10g'), '123.34')
752 self.assertEqual(format(123.34, '01f'), '123.340000')
753
754 self.assertEqual(format(-123.0, '00'), '-123.0')
755 self.assertEqual(format(-123.34, '00f'), '-123.340000')
756 self.assertEqual(format(-123.34, '00e'), '-1.233400e+02')
757 self.assertEqual(format(-123.34, '00g'), '-123.34')
758 self.assertEqual(format(-123.34, '00.10f'), '-123.3400000000')
759 self.assertEqual(format(-123.34, '00.10f'), '-123.3400000000')
760 self.assertEqual(format(-123.34, '00.10e'), '-1.2334000000e+02')
761 self.assertEqual(format(-123.34, '00.10g'), '-123.34')
762
763 class ESC[4;38;5;81mReprTestCase(ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
764 def test_repr(self):
765 with open(os.path.join(os.path.split(__file__)[0],
766 'floating_points.txt'), encoding="utf-8") as floats_file:
767 for line in floats_file:
768 line = line.strip()
769 if not line or line.startswith('#'):
770 continue
771 v = eval(line)
772 self.assertEqual(v, eval(repr(v)))
773
774 @unittest.skipUnless(getattr(sys, 'float_repr_style', '') == 'short',
775 "applies only when using short float repr style")
776 def test_short_repr(self):
777 # test short float repr introduced in Python 3.1. One aspect
778 # of this repr is that we get some degree of str -> float ->
779 # str roundtripping. In particular, for any numeric string
780 # containing 15 or fewer significant digits, those exact same
781 # digits (modulo trailing zeros) should appear in the output.
782 # No more repr(0.03) -> "0.029999999999999999"!
783
784 test_strings = [
785 # output always includes *either* a decimal point and at
786 # least one digit after that point, or an exponent.
787 '0.0',
788 '1.0',
789 '0.01',
790 '0.02',
791 '0.03',
792 '0.04',
793 '0.05',
794 '1.23456789',
795 '10.0',
796 '100.0',
797 # values >= 1e16 get an exponent...
798 '1000000000000000.0',
799 '9999999999999990.0',
800 '1e+16',
801 '1e+17',
802 # ... and so do values < 1e-4
803 '0.001',
804 '0.001001',
805 '0.00010000000000001',
806 '0.0001',
807 '9.999999999999e-05',
808 '1e-05',
809 # values designed to provoke failure if the FPU rounding
810 # precision isn't set correctly
811 '8.72293771110361e+25',
812 '7.47005307342313e+26',
813 '2.86438000439698e+28',
814 '8.89142905246179e+28',
815 '3.08578087079232e+35',
816 ]
817
818 for s in test_strings:
819 negs = '-'+s
820 self.assertEqual(s, repr(float(s)))
821 self.assertEqual(negs, repr(float(negs)))
822 # Since Python 3.2, repr and str are identical
823 self.assertEqual(repr(float(s)), str(float(s)))
824 self.assertEqual(repr(float(negs)), str(float(negs)))
825
826 @support.requires_IEEE_754
827 class ESC[4;38;5;81mRoundTestCase(ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
828
829 def test_inf_nan(self):
830 self.assertRaises(OverflowError, round, INF)
831 self.assertRaises(OverflowError, round, -INF)
832 self.assertRaises(ValueError, round, NAN)
833 self.assertRaises(TypeError, round, INF, 0.0)
834 self.assertRaises(TypeError, round, -INF, 1.0)
835 self.assertRaises(TypeError, round, NAN, "ceci n'est pas un integer")
836 self.assertRaises(TypeError, round, -0.0, 1j)
837
838 def test_inf_nan_ndigits(self):
839 self.assertEqual(round(INF, 0), INF)
840 self.assertEqual(round(-INF, 0), -INF)
841 self.assertTrue(math.isnan(round(NAN, 0)))
842
843 def test_large_n(self):
844 for n in [324, 325, 400, 2**31-1, 2**31, 2**32, 2**100]:
845 self.assertEqual(round(123.456, n), 123.456)
846 self.assertEqual(round(-123.456, n), -123.456)
847 self.assertEqual(round(1e300, n), 1e300)
848 self.assertEqual(round(1e-320, n), 1e-320)
849 self.assertEqual(round(1e150, 300), 1e150)
850 self.assertEqual(round(1e300, 307), 1e300)
851 self.assertEqual(round(-3.1415, 308), -3.1415)
852 self.assertEqual(round(1e150, 309), 1e150)
853 self.assertEqual(round(1.4e-315, 315), 1e-315)
854
855 def test_small_n(self):
856 for n in [-308, -309, -400, 1-2**31, -2**31, -2**31-1, -2**100]:
857 self.assertEqual(round(123.456, n), 0.0)
858 self.assertEqual(round(-123.456, n), -0.0)
859 self.assertEqual(round(1e300, n), 0.0)
860 self.assertEqual(round(1e-320, n), 0.0)
861
862 def test_overflow(self):
863 self.assertRaises(OverflowError, round, 1.6e308, -308)
864 self.assertRaises(OverflowError, round, -1.7e308, -308)
865
866 @unittest.skipUnless(getattr(sys, 'float_repr_style', '') == 'short',
867 "applies only when using short float repr style")
868 def test_previous_round_bugs(self):
869 # particular cases that have occurred in bug reports
870 self.assertEqual(round(562949953421312.5, 1),
871 562949953421312.5)
872 self.assertEqual(round(56294995342131.5, 3),
873 56294995342131.5)
874 # round-half-even
875 self.assertEqual(round(25.0, -1), 20.0)
876 self.assertEqual(round(35.0, -1), 40.0)
877 self.assertEqual(round(45.0, -1), 40.0)
878 self.assertEqual(round(55.0, -1), 60.0)
879 self.assertEqual(round(65.0, -1), 60.0)
880 self.assertEqual(round(75.0, -1), 80.0)
881 self.assertEqual(round(85.0, -1), 80.0)
882 self.assertEqual(round(95.0, -1), 100.0)
883
884 @unittest.skipUnless(getattr(sys, 'float_repr_style', '') == 'short',
885 "applies only when using short float repr style")
886 def test_matches_float_format(self):
887 # round should give the same results as float formatting
888 for i in range(500):
889 x = i/1000.
890 self.assertEqual(float(format(x, '.0f')), round(x, 0))
891 self.assertEqual(float(format(x, '.1f')), round(x, 1))
892 self.assertEqual(float(format(x, '.2f')), round(x, 2))
893 self.assertEqual(float(format(x, '.3f')), round(x, 3))
894
895 for i in range(5, 5000, 10):
896 x = i/1000.
897 self.assertEqual(float(format(x, '.0f')), round(x, 0))
898 self.assertEqual(float(format(x, '.1f')), round(x, 1))
899 self.assertEqual(float(format(x, '.2f')), round(x, 2))
900 self.assertEqual(float(format(x, '.3f')), round(x, 3))
901
902 for i in range(500):
903 x = random.random()
904 self.assertEqual(float(format(x, '.0f')), round(x, 0))
905 self.assertEqual(float(format(x, '.1f')), round(x, 1))
906 self.assertEqual(float(format(x, '.2f')), round(x, 2))
907 self.assertEqual(float(format(x, '.3f')), round(x, 3))
908
909 def test_format_specials(self):
910 # Test formatting of nans and infs.
911
912 def test(fmt, value, expected):
913 # Test with both % and format().
914 self.assertEqual(fmt % value, expected, fmt)
915 fmt = fmt[1:] # strip off the %
916 self.assertEqual(format(value, fmt), expected, fmt)
917
918 for fmt in ['%e', '%f', '%g', '%.0e', '%.6f', '%.20g',
919 '%#e', '%#f', '%#g', '%#.20e', '%#.15f', '%#.3g']:
920 pfmt = '%+' + fmt[1:]
921 sfmt = '% ' + fmt[1:]
922 test(fmt, INF, 'inf')
923 test(fmt, -INF, '-inf')
924 test(fmt, NAN, 'nan')
925 test(fmt, -NAN, 'nan')
926 # When asking for a sign, it's always provided. nans are
927 # always positive.
928 test(pfmt, INF, '+inf')
929 test(pfmt, -INF, '-inf')
930 test(pfmt, NAN, '+nan')
931 test(pfmt, -NAN, '+nan')
932 # When using ' ' for a sign code, only infs can be negative.
933 # Others have a space.
934 test(sfmt, INF, ' inf')
935 test(sfmt, -INF, '-inf')
936 test(sfmt, NAN, ' nan')
937 test(sfmt, -NAN, ' nan')
938
939 def test_None_ndigits(self):
940 for x in round(1.23), round(1.23, None), round(1.23, ndigits=None):
941 self.assertEqual(x, 1)
942 self.assertIsInstance(x, int)
943 for x in round(1.78), round(1.78, None), round(1.78, ndigits=None):
944 self.assertEqual(x, 2)
945 self.assertIsInstance(x, int)
946
947
948 # Beginning with Python 2.6 float has cross platform compatible
949 # ways to create and represent inf and nan
950 class ESC[4;38;5;81mInfNanTest(ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
951 def test_inf_from_str(self):
952 self.assertTrue(isinf(float("inf")))
953 self.assertTrue(isinf(float("+inf")))
954 self.assertTrue(isinf(float("-inf")))
955 self.assertTrue(isinf(float("infinity")))
956 self.assertTrue(isinf(float("+infinity")))
957 self.assertTrue(isinf(float("-infinity")))
958
959 self.assertEqual(repr(float("inf")), "inf")
960 self.assertEqual(repr(float("+inf")), "inf")
961 self.assertEqual(repr(float("-inf")), "-inf")
962 self.assertEqual(repr(float("infinity")), "inf")
963 self.assertEqual(repr(float("+infinity")), "inf")
964 self.assertEqual(repr(float("-infinity")), "-inf")
965
966 self.assertEqual(repr(float("INF")), "inf")
967 self.assertEqual(repr(float("+Inf")), "inf")
968 self.assertEqual(repr(float("-iNF")), "-inf")
969 self.assertEqual(repr(float("Infinity")), "inf")
970 self.assertEqual(repr(float("+iNfInItY")), "inf")
971 self.assertEqual(repr(float("-INFINITY")), "-inf")
972
973 self.assertEqual(str(float("inf")), "inf")
974 self.assertEqual(str(float("+inf")), "inf")
975 self.assertEqual(str(float("-inf")), "-inf")
976 self.assertEqual(str(float("infinity")), "inf")
977 self.assertEqual(str(float("+infinity")), "inf")
978 self.assertEqual(str(float("-infinity")), "-inf")
979
980 self.assertRaises(ValueError, float, "info")
981 self.assertRaises(ValueError, float, "+info")
982 self.assertRaises(ValueError, float, "-info")
983 self.assertRaises(ValueError, float, "in")
984 self.assertRaises(ValueError, float, "+in")
985 self.assertRaises(ValueError, float, "-in")
986 self.assertRaises(ValueError, float, "infinit")
987 self.assertRaises(ValueError, float, "+Infin")
988 self.assertRaises(ValueError, float, "-INFI")
989 self.assertRaises(ValueError, float, "infinitys")
990
991 self.assertRaises(ValueError, float, "++Inf")
992 self.assertRaises(ValueError, float, "-+inf")
993 self.assertRaises(ValueError, float, "+-infinity")
994 self.assertRaises(ValueError, float, "--Infinity")
995
996 def test_inf_as_str(self):
997 self.assertEqual(repr(1e300 * 1e300), "inf")
998 self.assertEqual(repr(-1e300 * 1e300), "-inf")
999
1000 self.assertEqual(str(1e300 * 1e300), "inf")
1001 self.assertEqual(str(-1e300 * 1e300), "-inf")
1002
1003 def test_nan_from_str(self):
1004 self.assertTrue(isnan(float("nan")))
1005 self.assertTrue(isnan(float("+nan")))
1006 self.assertTrue(isnan(float("-nan")))
1007
1008 self.assertEqual(repr(float("nan")), "nan")
1009 self.assertEqual(repr(float("+nan")), "nan")
1010 self.assertEqual(repr(float("-nan")), "nan")
1011
1012 self.assertEqual(repr(float("NAN")), "nan")
1013 self.assertEqual(repr(float("+NAn")), "nan")
1014 self.assertEqual(repr(float("-NaN")), "nan")
1015
1016 self.assertEqual(str(float("nan")), "nan")
1017 self.assertEqual(str(float("+nan")), "nan")
1018 self.assertEqual(str(float("-nan")), "nan")
1019
1020 self.assertRaises(ValueError, float, "nana")
1021 self.assertRaises(ValueError, float, "+nana")
1022 self.assertRaises(ValueError, float, "-nana")
1023 self.assertRaises(ValueError, float, "na")
1024 self.assertRaises(ValueError, float, "+na")
1025 self.assertRaises(ValueError, float, "-na")
1026
1027 self.assertRaises(ValueError, float, "++nan")
1028 self.assertRaises(ValueError, float, "-+NAN")
1029 self.assertRaises(ValueError, float, "+-NaN")
1030 self.assertRaises(ValueError, float, "--nAn")
1031
1032 def test_nan_as_str(self):
1033 self.assertEqual(repr(1e300 * 1e300 * 0), "nan")
1034 self.assertEqual(repr(-1e300 * 1e300 * 0), "nan")
1035
1036 self.assertEqual(str(1e300 * 1e300 * 0), "nan")
1037 self.assertEqual(str(-1e300 * 1e300 * 0), "nan")
1038
1039 def test_inf_signs(self):
1040 self.assertEqual(copysign(1.0, float('inf')), 1.0)
1041 self.assertEqual(copysign(1.0, float('-inf')), -1.0)
1042
1043 def test_nan_signs(self):
1044 # The sign of float('nan') should be predictable.
1045 self.assertEqual(copysign(1.0, float('nan')), 1.0)
1046 self.assertEqual(copysign(1.0, float('-nan')), -1.0)
1047
1048
1049 fromHex = float.fromhex
1050 toHex = float.hex
1051 class ESC[4;38;5;81mHexFloatTestCase(ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
1052 MAX = fromHex('0x.fffffffffffff8p+1024') # max normal
1053 MIN = fromHex('0x1p-1022') # min normal
1054 TINY = fromHex('0x0.0000000000001p-1022') # min subnormal
1055 EPS = fromHex('0x0.0000000000001p0') # diff between 1.0 and next float up
1056
1057 def identical(self, x, y):
1058 # check that floats x and y are identical, or that both
1059 # are NaNs
1060 if isnan(x) or isnan(y):
1061 if isnan(x) == isnan(y):
1062 return
1063 elif x == y and (x != 0.0 or copysign(1.0, x) == copysign(1.0, y)):
1064 return
1065 self.fail('%r not identical to %r' % (x, y))
1066
1067 def test_ends(self):
1068 self.identical(self.MIN, ldexp(1.0, -1022))
1069 self.identical(self.TINY, ldexp(1.0, -1074))
1070 self.identical(self.EPS, ldexp(1.0, -52))
1071 self.identical(self.MAX, 2.*(ldexp(1.0, 1023) - ldexp(1.0, 970)))
1072
1073 def test_invalid_inputs(self):
1074 invalid_inputs = [
1075 'infi', # misspelt infinities and nans
1076 '-Infinit',
1077 '++inf',
1078 '-+Inf',
1079 '--nan',
1080 '+-NaN',
1081 'snan',
1082 'NaNs',
1083 'nna',
1084 'an',
1085 'nf',
1086 'nfinity',
1087 'inity',
1088 'iinity',
1089 '0xnan',
1090 '',
1091 ' ',
1092 'x1.0p0',
1093 '0xX1.0p0',
1094 '+ 0x1.0p0', # internal whitespace
1095 '- 0x1.0p0',
1096 '0 x1.0p0',
1097 '0x 1.0p0',
1098 '0x1 2.0p0',
1099 '+0x1 .0p0',
1100 '0x1. 0p0',
1101 '-0x1.0 1p0',
1102 '-0x1.0 p0',
1103 '+0x1.0p +0',
1104 '0x1.0p -0',
1105 '0x1.0p 0',
1106 '+0x1.0p+ 0',
1107 '-0x1.0p- 0',
1108 '++0x1.0p-0', # double signs
1109 '--0x1.0p0',
1110 '+-0x1.0p+0',
1111 '-+0x1.0p0',
1112 '0x1.0p++0',
1113 '+0x1.0p+-0',
1114 '-0x1.0p-+0',
1115 '0x1.0p--0',
1116 '0x1.0.p0',
1117 '0x.p0', # no hex digits before or after point
1118 '0x1,p0', # wrong decimal point character
1119 '0x1pa',
1120 '0x1p\uff10', # fullwidth Unicode digits
1121 '\uff10x1p0',
1122 '0x\uff11p0',
1123 '0x1.\uff10p0',
1124 '0x1p0 \n 0x2p0',
1125 '0x1p0\0 0x1p0', # embedded null byte is not end of string
1126 ]
1127 for x in invalid_inputs:
1128 try:
1129 result = fromHex(x)
1130 except ValueError:
1131 pass
1132 else:
1133 self.fail('Expected float.fromhex(%r) to raise ValueError; '
1134 'got %r instead' % (x, result))
1135
1136
1137 def test_whitespace(self):
1138 value_pairs = [
1139 ('inf', INF),
1140 ('-Infinity', -INF),
1141 ('nan', NAN),
1142 ('1.0', 1.0),
1143 ('-0x.2', -0.125),
1144 ('-0.0', -0.0)
1145 ]
1146 whitespace = [
1147 '',
1148 ' ',
1149 '\t',
1150 '\n',
1151 '\n \t',
1152 '\f',
1153 '\v',
1154 '\r'
1155 ]
1156 for inp, expected in value_pairs:
1157 for lead in whitespace:
1158 for trail in whitespace:
1159 got = fromHex(lead + inp + trail)
1160 self.identical(got, expected)
1161
1162
1163 def test_from_hex(self):
1164 MIN = self.MIN
1165 MAX = self.MAX
1166 TINY = self.TINY
1167 EPS = self.EPS
1168
1169 # two spellings of infinity, with optional signs; case-insensitive
1170 self.identical(fromHex('inf'), INF)
1171 self.identical(fromHex('+Inf'), INF)
1172 self.identical(fromHex('-INF'), -INF)
1173 self.identical(fromHex('iNf'), INF)
1174 self.identical(fromHex('Infinity'), INF)
1175 self.identical(fromHex('+INFINITY'), INF)
1176 self.identical(fromHex('-infinity'), -INF)
1177 self.identical(fromHex('-iNFiNitY'), -INF)
1178
1179 # nans with optional sign; case insensitive
1180 self.identical(fromHex('nan'), NAN)
1181 self.identical(fromHex('+NaN'), NAN)
1182 self.identical(fromHex('-NaN'), NAN)
1183 self.identical(fromHex('-nAN'), NAN)
1184
1185 # variations in input format
1186 self.identical(fromHex('1'), 1.0)
1187 self.identical(fromHex('+1'), 1.0)
1188 self.identical(fromHex('1.'), 1.0)
1189 self.identical(fromHex('1.0'), 1.0)
1190 self.identical(fromHex('1.0p0'), 1.0)
1191 self.identical(fromHex('01'), 1.0)
1192 self.identical(fromHex('01.'), 1.0)
1193 self.identical(fromHex('0x1'), 1.0)
1194 self.identical(fromHex('0x1.'), 1.0)
1195 self.identical(fromHex('0x1.0'), 1.0)
1196 self.identical(fromHex('+0x1.0'), 1.0)
1197 self.identical(fromHex('0x1p0'), 1.0)
1198 self.identical(fromHex('0X1p0'), 1.0)
1199 self.identical(fromHex('0X1P0'), 1.0)
1200 self.identical(fromHex('0x1P0'), 1.0)
1201 self.identical(fromHex('0x1.p0'), 1.0)
1202 self.identical(fromHex('0x1.0p0'), 1.0)
1203 self.identical(fromHex('0x.1p4'), 1.0)
1204 self.identical(fromHex('0x.1p04'), 1.0)
1205 self.identical(fromHex('0x.1p004'), 1.0)
1206 self.identical(fromHex('0x1p+0'), 1.0)
1207 self.identical(fromHex('0x1P-0'), 1.0)
1208 self.identical(fromHex('+0x1p0'), 1.0)
1209 self.identical(fromHex('0x01p0'), 1.0)
1210 self.identical(fromHex('0x1p00'), 1.0)
1211 self.identical(fromHex(' 0x1p0 '), 1.0)
1212 self.identical(fromHex('\n 0x1p0'), 1.0)
1213 self.identical(fromHex('0x1p0 \t'), 1.0)
1214 self.identical(fromHex('0xap0'), 10.0)
1215 self.identical(fromHex('0xAp0'), 10.0)
1216 self.identical(fromHex('0xaP0'), 10.0)
1217 self.identical(fromHex('0xAP0'), 10.0)
1218 self.identical(fromHex('0xbep0'), 190.0)
1219 self.identical(fromHex('0xBep0'), 190.0)
1220 self.identical(fromHex('0xbEp0'), 190.0)
1221 self.identical(fromHex('0XBE0P-4'), 190.0)
1222 self.identical(fromHex('0xBEp0'), 190.0)
1223 self.identical(fromHex('0xB.Ep4'), 190.0)
1224 self.identical(fromHex('0x.BEp8'), 190.0)
1225 self.identical(fromHex('0x.0BEp12'), 190.0)
1226
1227 # moving the point around
1228 pi = fromHex('0x1.921fb54442d18p1')
1229 self.identical(fromHex('0x.006487ed5110b46p11'), pi)
1230 self.identical(fromHex('0x.00c90fdaa22168cp10'), pi)
1231 self.identical(fromHex('0x.01921fb54442d18p9'), pi)
1232 self.identical(fromHex('0x.03243f6a8885a3p8'), pi)
1233 self.identical(fromHex('0x.06487ed5110b46p7'), pi)
1234 self.identical(fromHex('0x.0c90fdaa22168cp6'), pi)
1235 self.identical(fromHex('0x.1921fb54442d18p5'), pi)
1236 self.identical(fromHex('0x.3243f6a8885a3p4'), pi)
1237 self.identical(fromHex('0x.6487ed5110b46p3'), pi)
1238 self.identical(fromHex('0x.c90fdaa22168cp2'), pi)
1239 self.identical(fromHex('0x1.921fb54442d18p1'), pi)
1240 self.identical(fromHex('0x3.243f6a8885a3p0'), pi)
1241 self.identical(fromHex('0x6.487ed5110b46p-1'), pi)
1242 self.identical(fromHex('0xc.90fdaa22168cp-2'), pi)
1243 self.identical(fromHex('0x19.21fb54442d18p-3'), pi)
1244 self.identical(fromHex('0x32.43f6a8885a3p-4'), pi)
1245 self.identical(fromHex('0x64.87ed5110b46p-5'), pi)
1246 self.identical(fromHex('0xc9.0fdaa22168cp-6'), pi)
1247 self.identical(fromHex('0x192.1fb54442d18p-7'), pi)
1248 self.identical(fromHex('0x324.3f6a8885a3p-8'), pi)
1249 self.identical(fromHex('0x648.7ed5110b46p-9'), pi)
1250 self.identical(fromHex('0xc90.fdaa22168cp-10'), pi)
1251 self.identical(fromHex('0x1921.fb54442d18p-11'), pi)
1252 # ...
1253 self.identical(fromHex('0x1921fb54442d1.8p-47'), pi)
1254 self.identical(fromHex('0x3243f6a8885a3p-48'), pi)
1255 self.identical(fromHex('0x6487ed5110b46p-49'), pi)
1256 self.identical(fromHex('0xc90fdaa22168cp-50'), pi)
1257 self.identical(fromHex('0x1921fb54442d18p-51'), pi)
1258 self.identical(fromHex('0x3243f6a8885a30p-52'), pi)
1259 self.identical(fromHex('0x6487ed5110b460p-53'), pi)
1260 self.identical(fromHex('0xc90fdaa22168c0p-54'), pi)
1261 self.identical(fromHex('0x1921fb54442d180p-55'), pi)
1262
1263
1264 # results that should overflow...
1265 self.assertRaises(OverflowError, fromHex, '-0x1p1024')
1266 self.assertRaises(OverflowError, fromHex, '0x1p+1025')
1267 self.assertRaises(OverflowError, fromHex, '+0X1p1030')
1268 self.assertRaises(OverflowError, fromHex, '-0x1p+1100')
1269 self.assertRaises(OverflowError, fromHex, '0X1p123456789123456789')
1270 self.assertRaises(OverflowError, fromHex, '+0X.8p+1025')
1271 self.assertRaises(OverflowError, fromHex, '+0x0.8p1025')
1272 self.assertRaises(OverflowError, fromHex, '-0x0.4p1026')
1273 self.assertRaises(OverflowError, fromHex, '0X2p+1023')
1274 self.assertRaises(OverflowError, fromHex, '0x2.p1023')
1275 self.assertRaises(OverflowError, fromHex, '-0x2.0p+1023')
1276 self.assertRaises(OverflowError, fromHex, '+0X4p+1022')
1277 self.assertRaises(OverflowError, fromHex, '0x1.ffffffffffffffp+1023')
1278 self.assertRaises(OverflowError, fromHex, '-0X1.fffffffffffff9p1023')
1279 self.assertRaises(OverflowError, fromHex, '0X1.fffffffffffff8p1023')
1280 self.assertRaises(OverflowError, fromHex, '+0x3.fffffffffffffp1022')
1281 self.assertRaises(OverflowError, fromHex, '0x3fffffffffffffp+970')
1282 self.assertRaises(OverflowError, fromHex, '0x10000000000000000p960')
1283 self.assertRaises(OverflowError, fromHex, '-0Xffffffffffffffffp960')
1284
1285 # ...and those that round to +-max float
1286 self.identical(fromHex('+0x1.fffffffffffffp+1023'), MAX)
1287 self.identical(fromHex('-0X1.fffffffffffff7p1023'), -MAX)
1288 self.identical(fromHex('0X1.fffffffffffff7fffffffffffffp1023'), MAX)
1289
1290 # zeros
1291 self.identical(fromHex('0x0p0'), 0.0)
1292 self.identical(fromHex('0x0p1000'), 0.0)
1293 self.identical(fromHex('-0x0p1023'), -0.0)
1294 self.identical(fromHex('0X0p1024'), 0.0)
1295 self.identical(fromHex('-0x0p1025'), -0.0)
1296 self.identical(fromHex('0X0p2000'), 0.0)
1297 self.identical(fromHex('0x0p123456789123456789'), 0.0)
1298 self.identical(fromHex('-0X0p-0'), -0.0)
1299 self.identical(fromHex('-0X0p-1000'), -0.0)
1300 self.identical(fromHex('0x0p-1023'), 0.0)
1301 self.identical(fromHex('-0X0p-1024'), -0.0)
1302 self.identical(fromHex('-0x0p-1025'), -0.0)
1303 self.identical(fromHex('-0x0p-1072'), -0.0)
1304 self.identical(fromHex('0X0p-1073'), 0.0)
1305 self.identical(fromHex('-0x0p-1074'), -0.0)
1306 self.identical(fromHex('0x0p-1075'), 0.0)
1307 self.identical(fromHex('0X0p-1076'), 0.0)
1308 self.identical(fromHex('-0X0p-2000'), -0.0)
1309 self.identical(fromHex('-0x0p-123456789123456789'), -0.0)
1310
1311 # values that should underflow to 0
1312 self.identical(fromHex('0X1p-1075'), 0.0)
1313 self.identical(fromHex('-0X1p-1075'), -0.0)
1314 self.identical(fromHex('-0x1p-123456789123456789'), -0.0)
1315 self.identical(fromHex('0x1.00000000000000001p-1075'), TINY)
1316 self.identical(fromHex('-0x1.1p-1075'), -TINY)
1317 self.identical(fromHex('0x1.fffffffffffffffffp-1075'), TINY)
1318
1319 # check round-half-even is working correctly near 0 ...
1320 self.identical(fromHex('0x1p-1076'), 0.0)
1321 self.identical(fromHex('0X2p-1076'), 0.0)
1322 self.identical(fromHex('0X3p-1076'), TINY)
1323 self.identical(fromHex('0x4p-1076'), TINY)
1324 self.identical(fromHex('0X5p-1076'), TINY)
1325 self.identical(fromHex('0X6p-1076'), 2*TINY)
1326 self.identical(fromHex('0x7p-1076'), 2*TINY)
1327 self.identical(fromHex('0X8p-1076'), 2*TINY)
1328 self.identical(fromHex('0X9p-1076'), 2*TINY)
1329 self.identical(fromHex('0xap-1076'), 2*TINY)
1330 self.identical(fromHex('0Xbp-1076'), 3*TINY)
1331 self.identical(fromHex('0xcp-1076'), 3*TINY)
1332 self.identical(fromHex('0Xdp-1076'), 3*TINY)
1333 self.identical(fromHex('0Xep-1076'), 4*TINY)
1334 self.identical(fromHex('0xfp-1076'), 4*TINY)
1335 self.identical(fromHex('0x10p-1076'), 4*TINY)
1336 self.identical(fromHex('-0x1p-1076'), -0.0)
1337 self.identical(fromHex('-0X2p-1076'), -0.0)
1338 self.identical(fromHex('-0x3p-1076'), -TINY)
1339 self.identical(fromHex('-0X4p-1076'), -TINY)
1340 self.identical(fromHex('-0x5p-1076'), -TINY)
1341 self.identical(fromHex('-0x6p-1076'), -2*TINY)
1342 self.identical(fromHex('-0X7p-1076'), -2*TINY)
1343 self.identical(fromHex('-0X8p-1076'), -2*TINY)
1344 self.identical(fromHex('-0X9p-1076'), -2*TINY)
1345 self.identical(fromHex('-0Xap-1076'), -2*TINY)
1346 self.identical(fromHex('-0xbp-1076'), -3*TINY)
1347 self.identical(fromHex('-0xcp-1076'), -3*TINY)
1348 self.identical(fromHex('-0Xdp-1076'), -3*TINY)
1349 self.identical(fromHex('-0xep-1076'), -4*TINY)
1350 self.identical(fromHex('-0Xfp-1076'), -4*TINY)
1351 self.identical(fromHex('-0X10p-1076'), -4*TINY)
1352
1353 # ... and near MIN ...
1354 self.identical(fromHex('0x0.ffffffffffffd6p-1022'), MIN-3*TINY)
1355 self.identical(fromHex('0x0.ffffffffffffd8p-1022'), MIN-2*TINY)
1356 self.identical(fromHex('0x0.ffffffffffffdap-1022'), MIN-2*TINY)
1357 self.identical(fromHex('0x0.ffffffffffffdcp-1022'), MIN-2*TINY)
1358 self.identical(fromHex('0x0.ffffffffffffdep-1022'), MIN-2*TINY)
1359 self.identical(fromHex('0x0.ffffffffffffe0p-1022'), MIN-2*TINY)
1360 self.identical(fromHex('0x0.ffffffffffffe2p-1022'), MIN-2*TINY)
1361 self.identical(fromHex('0x0.ffffffffffffe4p-1022'), MIN-2*TINY)
1362 self.identical(fromHex('0x0.ffffffffffffe6p-1022'), MIN-2*TINY)
1363 self.identical(fromHex('0x0.ffffffffffffe8p-1022'), MIN-2*TINY)
1364 self.identical(fromHex('0x0.ffffffffffffeap-1022'), MIN-TINY)
1365 self.identical(fromHex('0x0.ffffffffffffecp-1022'), MIN-TINY)
1366 self.identical(fromHex('0x0.ffffffffffffeep-1022'), MIN-TINY)
1367 self.identical(fromHex('0x0.fffffffffffff0p-1022'), MIN-TINY)
1368 self.identical(fromHex('0x0.fffffffffffff2p-1022'), MIN-TINY)
1369 self.identical(fromHex('0x0.fffffffffffff4p-1022'), MIN-TINY)
1370 self.identical(fromHex('0x0.fffffffffffff6p-1022'), MIN-TINY)
1371 self.identical(fromHex('0x0.fffffffffffff8p-1022'), MIN)
1372 self.identical(fromHex('0x0.fffffffffffffap-1022'), MIN)
1373 self.identical(fromHex('0x0.fffffffffffffcp-1022'), MIN)
1374 self.identical(fromHex('0x0.fffffffffffffep-1022'), MIN)
1375 self.identical(fromHex('0x1.00000000000000p-1022'), MIN)
1376 self.identical(fromHex('0x1.00000000000002p-1022'), MIN)
1377 self.identical(fromHex('0x1.00000000000004p-1022'), MIN)
1378 self.identical(fromHex('0x1.00000000000006p-1022'), MIN)
1379 self.identical(fromHex('0x1.00000000000008p-1022'), MIN)
1380 self.identical(fromHex('0x1.0000000000000ap-1022'), MIN+TINY)
1381 self.identical(fromHex('0x1.0000000000000cp-1022'), MIN+TINY)
1382 self.identical(fromHex('0x1.0000000000000ep-1022'), MIN+TINY)
1383 self.identical(fromHex('0x1.00000000000010p-1022'), MIN+TINY)
1384 self.identical(fromHex('0x1.00000000000012p-1022'), MIN+TINY)
1385 self.identical(fromHex('0x1.00000000000014p-1022'), MIN+TINY)
1386 self.identical(fromHex('0x1.00000000000016p-1022'), MIN+TINY)
1387 self.identical(fromHex('0x1.00000000000018p-1022'), MIN+2*TINY)
1388
1389 # ... and near 1.0.
1390 self.identical(fromHex('0x0.fffffffffffff0p0'), 1.0-EPS)
1391 self.identical(fromHex('0x0.fffffffffffff1p0'), 1.0-EPS)
1392 self.identical(fromHex('0X0.fffffffffffff2p0'), 1.0-EPS)
1393 self.identical(fromHex('0x0.fffffffffffff3p0'), 1.0-EPS)
1394 self.identical(fromHex('0X0.fffffffffffff4p0'), 1.0-EPS)
1395 self.identical(fromHex('0X0.fffffffffffff5p0'), 1.0-EPS/2)
1396 self.identical(fromHex('0X0.fffffffffffff6p0'), 1.0-EPS/2)
1397 self.identical(fromHex('0x0.fffffffffffff7p0'), 1.0-EPS/2)
1398 self.identical(fromHex('0x0.fffffffffffff8p0'), 1.0-EPS/2)
1399 self.identical(fromHex('0X0.fffffffffffff9p0'), 1.0-EPS/2)
1400 self.identical(fromHex('0X0.fffffffffffffap0'), 1.0-EPS/2)
1401 self.identical(fromHex('0x0.fffffffffffffbp0'), 1.0-EPS/2)
1402 self.identical(fromHex('0X0.fffffffffffffcp0'), 1.0)
1403 self.identical(fromHex('0x0.fffffffffffffdp0'), 1.0)
1404 self.identical(fromHex('0X0.fffffffffffffep0'), 1.0)
1405 self.identical(fromHex('0x0.ffffffffffffffp0'), 1.0)
1406 self.identical(fromHex('0X1.00000000000000p0'), 1.0)
1407 self.identical(fromHex('0X1.00000000000001p0'), 1.0)
1408 self.identical(fromHex('0x1.00000000000002p0'), 1.0)
1409 self.identical(fromHex('0X1.00000000000003p0'), 1.0)
1410 self.identical(fromHex('0x1.00000000000004p0'), 1.0)
1411 self.identical(fromHex('0X1.00000000000005p0'), 1.0)
1412 self.identical(fromHex('0X1.00000000000006p0'), 1.0)
1413 self.identical(fromHex('0X1.00000000000007p0'), 1.0)
1414 self.identical(fromHex('0x1.00000000000007ffffffffffffffffffffp0'),
1415 1.0)
1416 self.identical(fromHex('0x1.00000000000008p0'), 1.0)
1417 self.identical(fromHex('0x1.00000000000008000000000000000001p0'),
1418 1+EPS)
1419 self.identical(fromHex('0X1.00000000000009p0'), 1.0+EPS)
1420 self.identical(fromHex('0x1.0000000000000ap0'), 1.0+EPS)
1421 self.identical(fromHex('0x1.0000000000000bp0'), 1.0+EPS)
1422 self.identical(fromHex('0X1.0000000000000cp0'), 1.0+EPS)
1423 self.identical(fromHex('0x1.0000000000000dp0'), 1.0+EPS)
1424 self.identical(fromHex('0x1.0000000000000ep0'), 1.0+EPS)
1425 self.identical(fromHex('0X1.0000000000000fp0'), 1.0+EPS)
1426 self.identical(fromHex('0x1.00000000000010p0'), 1.0+EPS)
1427 self.identical(fromHex('0X1.00000000000011p0'), 1.0+EPS)
1428 self.identical(fromHex('0x1.00000000000012p0'), 1.0+EPS)
1429 self.identical(fromHex('0X1.00000000000013p0'), 1.0+EPS)
1430 self.identical(fromHex('0X1.00000000000014p0'), 1.0+EPS)
1431 self.identical(fromHex('0x1.00000000000015p0'), 1.0+EPS)
1432 self.identical(fromHex('0x1.00000000000016p0'), 1.0+EPS)
1433 self.identical(fromHex('0X1.00000000000017p0'), 1.0+EPS)
1434 self.identical(fromHex('0x1.00000000000017ffffffffffffffffffffp0'),
1435 1.0+EPS)
1436 self.identical(fromHex('0x1.00000000000018p0'), 1.0+2*EPS)
1437 self.identical(fromHex('0X1.00000000000018000000000000000001p0'),
1438 1.0+2*EPS)
1439 self.identical(fromHex('0x1.00000000000019p0'), 1.0+2*EPS)
1440 self.identical(fromHex('0X1.0000000000001ap0'), 1.0+2*EPS)
1441 self.identical(fromHex('0X1.0000000000001bp0'), 1.0+2*EPS)
1442 self.identical(fromHex('0x1.0000000000001cp0'), 1.0+2*EPS)
1443 self.identical(fromHex('0x1.0000000000001dp0'), 1.0+2*EPS)
1444 self.identical(fromHex('0x1.0000000000001ep0'), 1.0+2*EPS)
1445 self.identical(fromHex('0X1.0000000000001fp0'), 1.0+2*EPS)
1446 self.identical(fromHex('0x1.00000000000020p0'), 1.0+2*EPS)
1447
1448 # Regression test for a corner-case bug reported in b.p.o. 44954
1449 self.identical(fromHex('0x.8p-1074'), 0.0)
1450 self.identical(fromHex('0x.80p-1074'), 0.0)
1451 self.identical(fromHex('0x.81p-1074'), TINY)
1452 self.identical(fromHex('0x8p-1078'), 0.0)
1453 self.identical(fromHex('0x8.0p-1078'), 0.0)
1454 self.identical(fromHex('0x8.1p-1078'), TINY)
1455 self.identical(fromHex('0x80p-1082'), 0.0)
1456 self.identical(fromHex('0x81p-1082'), TINY)
1457 self.identical(fromHex('.8p-1074'), 0.0)
1458 self.identical(fromHex('8p-1078'), 0.0)
1459 self.identical(fromHex('-.8p-1074'), -0.0)
1460 self.identical(fromHex('+8p-1078'), 0.0)
1461
1462 def test_roundtrip(self):
1463 def roundtrip(x):
1464 return fromHex(toHex(x))
1465
1466 for x in [NAN, INF, self.MAX, self.MIN, self.MIN-self.TINY, self.TINY, 0.0]:
1467 self.identical(x, roundtrip(x))
1468 self.identical(-x, roundtrip(-x))
1469
1470 # fromHex(toHex(x)) should exactly recover x, for any non-NaN float x.
1471 import random
1472 for i in range(10000):
1473 e = random.randrange(-1200, 1200)
1474 m = random.random()
1475 s = random.choice([1.0, -1.0])
1476 try:
1477 x = s*ldexp(m, e)
1478 except OverflowError:
1479 pass
1480 else:
1481 self.identical(x, fromHex(toHex(x)))
1482
1483 def test_subclass(self):
1484 class ESC[4;38;5;81mF(ESC[4;38;5;149mfloat):
1485 def __new__(cls, value):
1486 return float.__new__(cls, value + 1)
1487
1488 f = F.fromhex((1.5).hex())
1489 self.assertIs(type(f), F)
1490 self.assertEqual(f, 2.5)
1491
1492 class ESC[4;38;5;81mF2(ESC[4;38;5;149mfloat):
1493 def __init__(self, value):
1494 self.foo = 'bar'
1495
1496 f = F2.fromhex((1.5).hex())
1497 self.assertIs(type(f), F2)
1498 self.assertEqual(f, 1.5)
1499 self.assertEqual(getattr(f, 'foo', 'none'), 'bar')
1500
1501
1502 # Test PyFloat_Pack2(), PyFloat_Pack4() and PyFloat_Pack8()
1503 # Test PyFloat_Unpack2(), PyFloat_Unpack4() and PyFloat_Unpack8()
1504 BIG_ENDIAN = 0
1505 LITTLE_ENDIAN = 1
1506 EPSILON = {
1507 2: 2.0 ** -11, # binary16
1508 4: 2.0 ** -24, # binary32
1509 8: 2.0 ** -53, # binary64
1510 }
1511
1512 @unittest.skipIf(_testcapi is None, 'needs _testcapi')
1513 class ESC[4;38;5;81mPackTests(ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
1514 def test_pack(self):
1515 self.assertEqual(_testcapi.float_pack(2, 1.5, BIG_ENDIAN),
1516 b'>\x00')
1517 self.assertEqual(_testcapi.float_pack(4, 1.5, BIG_ENDIAN),
1518 b'?\xc0\x00\x00')
1519 self.assertEqual(_testcapi.float_pack(8, 1.5, BIG_ENDIAN),
1520 b'?\xf8\x00\x00\x00\x00\x00\x00')
1521 self.assertEqual(_testcapi.float_pack(2, 1.5, LITTLE_ENDIAN),
1522 b'\x00>')
1523 self.assertEqual(_testcapi.float_pack(4, 1.5, LITTLE_ENDIAN),
1524 b'\x00\x00\xc0?')
1525 self.assertEqual(_testcapi.float_pack(8, 1.5, LITTLE_ENDIAN),
1526 b'\x00\x00\x00\x00\x00\x00\xf8?')
1527
1528 def test_unpack(self):
1529 self.assertEqual(_testcapi.float_unpack(b'>\x00', BIG_ENDIAN),
1530 1.5)
1531 self.assertEqual(_testcapi.float_unpack(b'?\xc0\x00\x00', BIG_ENDIAN),
1532 1.5)
1533 self.assertEqual(_testcapi.float_unpack(b'?\xf8\x00\x00\x00\x00\x00\x00', BIG_ENDIAN),
1534 1.5)
1535 self.assertEqual(_testcapi.float_unpack(b'\x00>', LITTLE_ENDIAN),
1536 1.5)
1537 self.assertEqual(_testcapi.float_unpack(b'\x00\x00\xc0?', LITTLE_ENDIAN),
1538 1.5)
1539 self.assertEqual(_testcapi.float_unpack(b'\x00\x00\x00\x00\x00\x00\xf8?', LITTLE_ENDIAN),
1540 1.5)
1541
1542 def test_roundtrip(self):
1543 large = 2.0 ** 100
1544 values = [1.0, 1.5, large, 1.0/7, math.pi]
1545 if HAVE_IEEE_754:
1546 values.extend((INF, NAN))
1547 for value in values:
1548 for size in (2, 4, 8,):
1549 if size == 2 and value == large:
1550 # too large for 16-bit float
1551 continue
1552 rel_tol = EPSILON[size]
1553 for endian in (BIG_ENDIAN, LITTLE_ENDIAN):
1554 with self.subTest(value=value, size=size, endian=endian):
1555 data = _testcapi.float_pack(size, value, endian)
1556 value2 = _testcapi.float_unpack(data, endian)
1557 if isnan(value):
1558 self.assertTrue(isnan(value2), (value, value2))
1559 elif size < 8:
1560 self.assertTrue(math.isclose(value2, value, rel_tol=rel_tol),
1561 (value, value2))
1562 else:
1563 self.assertEqual(value2, value)
1564
1565
1566 if __name__ == '__main__':
1567 unittest.main()