• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1import fractions
2import operator
3import os
4import random
5import sys
6import struct
7import time
8import unittest
9
10from test import support
11from test.support.testcase import FloatsAreIdenticalMixin
12from test.test_grammar import (VALID_UNDERSCORE_LITERALS,
13                               INVALID_UNDERSCORE_LITERALS)
14from math import isinf, isnan, copysign, ldexp
15import math
16
17try:
18    import _testcapi
19except ImportError:
20    _testcapi = None
21
22INF = float("inf")
23NAN = float("nan")
24
25
26#locate file with float format test values
27test_dir = os.path.dirname(__file__) or os.curdir
28format_testfile = os.path.join(test_dir, 'mathdata', 'formatfloat_testcases.txt')
29
30class FloatSubclass(float):
31    pass
32
33class OtherFloatSubclass(float):
34    pass
35
36class GeneralFloatCases(unittest.TestCase):
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 CustomStr(str): pass
97        class CustomBytes(bytes): pass
98        class CustomByteArray(bytearray): 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 Foo1(object):
186            def __float__(self):
187                return 42.
188
189        class Foo2(float):
190            def __float__(self):
191                return 42.
192
193        class Foo3(float):
194            def __new__(cls, value=0.):
195                return float.__new__(cls, 2*value)
196
197            def __float__(self):
198                return self
199
200        class Foo4(float):
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 FooStr(str):
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 Foo5:
218            def __float__(self):
219                return ""
220        self.assertRaises(TypeError, time.sleep, Foo5())
221
222        # Issue #24731
223        class F:
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 MyIndex:
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 MyInt:
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 subclass(float):
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 subclass_with_init(float):
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 subclass_with_new(float):
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 H:
612            def __hash__(self):
613                return 42
614        class F(float, H):
615            pass
616        value = F('nan')
617        self.assertEqual(hash(value), object.__hash__(value))
618
619
620@unittest.skipUnless(hasattr(float, "__getformat__"), "requires __getformat__")
621class FormatFunctionsTestCase(unittest.TestCase):
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
631BE_DOUBLE_INF = b'\x7f\xf0\x00\x00\x00\x00\x00\x00'
632LE_DOUBLE_INF = bytes(reversed(BE_DOUBLE_INF))
633BE_DOUBLE_NAN = b'\x7f\xf8\x00\x00\x00\x00\x00\x00'
634LE_DOUBLE_NAN = bytes(reversed(BE_DOUBLE_NAN))
635
636BE_FLOAT_INF = b'\x7f\x80\x00\x00'
637LE_FLOAT_INF = bytes(reversed(BE_FLOAT_INF))
638BE_FLOAT_NAN = b'\x7f\xc0\x00\x00'
639LE_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
646class IEEEFormatTestCase(unittest.TestCase):
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
671class FormatTestCase(unittest.TestCase):
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                f = float(arg)
737                self.assertEqual(fmt % f, rhs)
738                self.assertEqual(fmt % -f, '-' + rhs)
739                if fmt != '%r':
740                    fmt2 = fmt[1:]
741                    self.assertEqual(format(f, fmt2), rhs)
742                    self.assertEqual(format(-f, fmt2), '-' + rhs)
743
744    def test_issue5864(self):
745        self.assertEqual(format(123.456, '.4'), '123.5')
746        self.assertEqual(format(1234.56, '.4'), '1.235e+03')
747        self.assertEqual(format(12345.6, '.4'), '1.235e+04')
748
749    def test_issue35560(self):
750        self.assertEqual(format(123.0, '00'), '123.0')
751        self.assertEqual(format(123.34, '00f'), '123.340000')
752        self.assertEqual(format(123.34, '00e'), '1.233400e+02')
753        self.assertEqual(format(123.34, '00g'), '123.34')
754        self.assertEqual(format(123.34, '00.10f'), '123.3400000000')
755        self.assertEqual(format(123.34, '00.10e'), '1.2334000000e+02')
756        self.assertEqual(format(123.34, '00.10g'), '123.34')
757        self.assertEqual(format(123.34, '01f'), '123.340000')
758
759        self.assertEqual(format(-123.0, '00'), '-123.0')
760        self.assertEqual(format(-123.34, '00f'), '-123.340000')
761        self.assertEqual(format(-123.34, '00e'), '-1.233400e+02')
762        self.assertEqual(format(-123.34, '00g'), '-123.34')
763        self.assertEqual(format(-123.34, '00.10f'), '-123.3400000000')
764        self.assertEqual(format(-123.34, '00.10f'), '-123.3400000000')
765        self.assertEqual(format(-123.34, '00.10e'), '-1.2334000000e+02')
766        self.assertEqual(format(-123.34, '00.10g'), '-123.34')
767
768class ReprTestCase(unittest.TestCase):
769    def test_repr(self):
770        with open(os.path.join(os.path.split(__file__)[0],
771                  'mathdata',
772                  'floating_points.txt'), encoding="utf-8") as floats_file:
773            for line in floats_file:
774                line = line.strip()
775                if not line or line.startswith('#'):
776                    continue
777                v = eval(line)
778                self.assertEqual(v, eval(repr(v)))
779
780    @unittest.skipUnless(getattr(sys, 'float_repr_style', '') == 'short',
781                         "applies only when using short float repr style")
782    def test_short_repr(self):
783        # test short float repr introduced in Python 3.1.  One aspect
784        # of this repr is that we get some degree of str -> float ->
785        # str roundtripping.  In particular, for any numeric string
786        # containing 15 or fewer significant digits, those exact same
787        # digits (modulo trailing zeros) should appear in the output.
788        # No more repr(0.03) -> "0.029999999999999999"!
789
790        test_strings = [
791            # output always includes *either* a decimal point and at
792            # least one digit after that point, or an exponent.
793            '0.0',
794            '1.0',
795            '0.01',
796            '0.02',
797            '0.03',
798            '0.04',
799            '0.05',
800            '1.23456789',
801            '10.0',
802            '100.0',
803            # values >= 1e16 get an exponent...
804            '1000000000000000.0',
805            '9999999999999990.0',
806            '1e+16',
807            '1e+17',
808            # ... and so do values < 1e-4
809            '0.001',
810            '0.001001',
811            '0.00010000000000001',
812            '0.0001',
813            '9.999999999999e-05',
814            '1e-05',
815            # values designed to provoke failure if the FPU rounding
816            # precision isn't set correctly
817            '8.72293771110361e+25',
818            '7.47005307342313e+26',
819            '2.86438000439698e+28',
820            '8.89142905246179e+28',
821            '3.08578087079232e+35',
822            ]
823
824        for s in test_strings:
825            negs = '-'+s
826            self.assertEqual(s, repr(float(s)))
827            self.assertEqual(negs, repr(float(negs)))
828            # Since Python 3.2, repr and str are identical
829            self.assertEqual(repr(float(s)), str(float(s)))
830            self.assertEqual(repr(float(negs)), str(float(negs)))
831
832@support.requires_IEEE_754
833class RoundTestCase(unittest.TestCase, FloatsAreIdenticalMixin):
834
835    def test_inf_nan(self):
836        self.assertRaises(OverflowError, round, INF)
837        self.assertRaises(OverflowError, round, -INF)
838        self.assertRaises(ValueError, round, NAN)
839        self.assertRaises(TypeError, round, INF, 0.0)
840        self.assertRaises(TypeError, round, -INF, 1.0)
841        self.assertRaises(TypeError, round, NAN, "ceci n'est pas un integer")
842        self.assertRaises(TypeError, round, -0.0, 1j)
843
844    def test_inf_nan_ndigits(self):
845        self.assertEqual(round(INF, 0), INF)
846        self.assertEqual(round(-INF, 0), -INF)
847        self.assertTrue(math.isnan(round(NAN, 0)))
848
849    def test_large_n(self):
850        for n in [324, 325, 400, 2**31-1, 2**31, 2**32, 2**100]:
851            self.assertEqual(round(123.456, n), 123.456)
852            self.assertEqual(round(-123.456, n), -123.456)
853            self.assertEqual(round(1e300, n), 1e300)
854            self.assertEqual(round(1e-320, n), 1e-320)
855        self.assertEqual(round(1e150, 300), 1e150)
856        self.assertEqual(round(1e300, 307), 1e300)
857        self.assertEqual(round(-3.1415, 308), -3.1415)
858        self.assertEqual(round(1e150, 309), 1e150)
859        self.assertEqual(round(1.4e-315, 315), 1e-315)
860
861    def test_small_n(self):
862        for n in [-308, -309, -400, 1-2**31, -2**31, -2**31-1, -2**100]:
863            self.assertFloatsAreIdentical(round(123.456, n), 0.0)
864            self.assertFloatsAreIdentical(round(-123.456, n), -0.0)
865            self.assertFloatsAreIdentical(round(1e300, n), 0.0)
866            self.assertFloatsAreIdentical(round(1e-320, n), 0.0)
867
868    def test_overflow(self):
869        self.assertRaises(OverflowError, round, 1.6e308, -308)
870        self.assertRaises(OverflowError, round, -1.7e308, -308)
871
872    @unittest.skipUnless(getattr(sys, 'float_repr_style', '') == 'short',
873                         "applies only when using short float repr style")
874    def test_previous_round_bugs(self):
875        # particular cases that have occurred in bug reports
876        self.assertEqual(round(562949953421312.5, 1),
877                          562949953421312.5)
878        self.assertEqual(round(56294995342131.5, 3),
879                         56294995342131.5)
880        # round-half-even
881        self.assertEqual(round(25.0, -1), 20.0)
882        self.assertEqual(round(35.0, -1), 40.0)
883        self.assertEqual(round(45.0, -1), 40.0)
884        self.assertEqual(round(55.0, -1), 60.0)
885        self.assertEqual(round(65.0, -1), 60.0)
886        self.assertEqual(round(75.0, -1), 80.0)
887        self.assertEqual(round(85.0, -1), 80.0)
888        self.assertEqual(round(95.0, -1), 100.0)
889
890    @unittest.skipUnless(getattr(sys, 'float_repr_style', '') == 'short',
891                         "applies only when using short float repr style")
892    def test_matches_float_format(self):
893        # round should give the same results as float formatting
894        for i in range(500):
895            x = i/1000.
896            self.assertEqual(float(format(x, '.0f')), round(x, 0))
897            self.assertEqual(float(format(x, '.1f')), round(x, 1))
898            self.assertEqual(float(format(x, '.2f')), round(x, 2))
899            self.assertEqual(float(format(x, '.3f')), round(x, 3))
900
901        for i in range(5, 5000, 10):
902            x = i/1000.
903            self.assertEqual(float(format(x, '.0f')), round(x, 0))
904            self.assertEqual(float(format(x, '.1f')), round(x, 1))
905            self.assertEqual(float(format(x, '.2f')), round(x, 2))
906            self.assertEqual(float(format(x, '.3f')), round(x, 3))
907
908        for i in range(500):
909            x = random.random()
910            self.assertEqual(float(format(x, '.0f')), round(x, 0))
911            self.assertEqual(float(format(x, '.1f')), round(x, 1))
912            self.assertEqual(float(format(x, '.2f')), round(x, 2))
913            self.assertEqual(float(format(x, '.3f')), round(x, 3))
914
915    def test_format_specials(self):
916        # Test formatting of nans and infs.
917
918        def test(fmt, value, expected):
919            # Test with both % and format().
920            self.assertEqual(fmt % value, expected, fmt)
921            fmt = fmt[1:] # strip off the %
922            self.assertEqual(format(value, fmt), expected, fmt)
923
924        for fmt in ['%e', '%f', '%g', '%.0e', '%.6f', '%.20g',
925                    '%#e', '%#f', '%#g', '%#.20e', '%#.15f', '%#.3g']:
926            pfmt = '%+' + fmt[1:]
927            sfmt = '% ' + fmt[1:]
928            test(fmt, INF, 'inf')
929            test(fmt, -INF, '-inf')
930            test(fmt, NAN, 'nan')
931            test(fmt, -NAN, 'nan')
932            # When asking for a sign, it's always provided. nans are
933            #  always positive.
934            test(pfmt, INF, '+inf')
935            test(pfmt, -INF, '-inf')
936            test(pfmt, NAN, '+nan')
937            test(pfmt, -NAN, '+nan')
938            # When using ' ' for a sign code, only infs can be negative.
939            #  Others have a space.
940            test(sfmt, INF, ' inf')
941            test(sfmt, -INF, '-inf')
942            test(sfmt, NAN, ' nan')
943            test(sfmt, -NAN, ' nan')
944
945    def test_None_ndigits(self):
946        for x in round(1.23), round(1.23, None), round(1.23, ndigits=None):
947            self.assertEqual(x, 1)
948            self.assertIsInstance(x, int)
949        for x in round(1.78), round(1.78, None), round(1.78, ndigits=None):
950            self.assertEqual(x, 2)
951            self.assertIsInstance(x, int)
952
953
954# Beginning with Python 2.6 float has cross platform compatible
955# ways to create and represent inf and nan
956class InfNanTest(unittest.TestCase):
957    def test_inf_from_str(self):
958        self.assertTrue(isinf(float("inf")))
959        self.assertTrue(isinf(float("+inf")))
960        self.assertTrue(isinf(float("-inf")))
961        self.assertTrue(isinf(float("infinity")))
962        self.assertTrue(isinf(float("+infinity")))
963        self.assertTrue(isinf(float("-infinity")))
964
965        self.assertEqual(repr(float("inf")), "inf")
966        self.assertEqual(repr(float("+inf")), "inf")
967        self.assertEqual(repr(float("-inf")), "-inf")
968        self.assertEqual(repr(float("infinity")), "inf")
969        self.assertEqual(repr(float("+infinity")), "inf")
970        self.assertEqual(repr(float("-infinity")), "-inf")
971
972        self.assertEqual(repr(float("INF")), "inf")
973        self.assertEqual(repr(float("+Inf")), "inf")
974        self.assertEqual(repr(float("-iNF")), "-inf")
975        self.assertEqual(repr(float("Infinity")), "inf")
976        self.assertEqual(repr(float("+iNfInItY")), "inf")
977        self.assertEqual(repr(float("-INFINITY")), "-inf")
978
979        self.assertEqual(str(float("inf")), "inf")
980        self.assertEqual(str(float("+inf")), "inf")
981        self.assertEqual(str(float("-inf")), "-inf")
982        self.assertEqual(str(float("infinity")), "inf")
983        self.assertEqual(str(float("+infinity")), "inf")
984        self.assertEqual(str(float("-infinity")), "-inf")
985
986        self.assertRaises(ValueError, float, "info")
987        self.assertRaises(ValueError, float, "+info")
988        self.assertRaises(ValueError, float, "-info")
989        self.assertRaises(ValueError, float, "in")
990        self.assertRaises(ValueError, float, "+in")
991        self.assertRaises(ValueError, float, "-in")
992        self.assertRaises(ValueError, float, "infinit")
993        self.assertRaises(ValueError, float, "+Infin")
994        self.assertRaises(ValueError, float, "-INFI")
995        self.assertRaises(ValueError, float, "infinitys")
996
997        self.assertRaises(ValueError, float, "++Inf")
998        self.assertRaises(ValueError, float, "-+inf")
999        self.assertRaises(ValueError, float, "+-infinity")
1000        self.assertRaises(ValueError, float, "--Infinity")
1001
1002    def test_inf_as_str(self):
1003        self.assertEqual(repr(1e300 * 1e300), "inf")
1004        self.assertEqual(repr(-1e300 * 1e300), "-inf")
1005
1006        self.assertEqual(str(1e300 * 1e300), "inf")
1007        self.assertEqual(str(-1e300 * 1e300), "-inf")
1008
1009    def test_nan_from_str(self):
1010        self.assertTrue(isnan(float("nan")))
1011        self.assertTrue(isnan(float("+nan")))
1012        self.assertTrue(isnan(float("-nan")))
1013
1014        self.assertEqual(repr(float("nan")), "nan")
1015        self.assertEqual(repr(float("+nan")), "nan")
1016        self.assertEqual(repr(float("-nan")), "nan")
1017
1018        self.assertEqual(repr(float("NAN")), "nan")
1019        self.assertEqual(repr(float("+NAn")), "nan")
1020        self.assertEqual(repr(float("-NaN")), "nan")
1021
1022        self.assertEqual(str(float("nan")), "nan")
1023        self.assertEqual(str(float("+nan")), "nan")
1024        self.assertEqual(str(float("-nan")), "nan")
1025
1026        self.assertRaises(ValueError, float, "nana")
1027        self.assertRaises(ValueError, float, "+nana")
1028        self.assertRaises(ValueError, float, "-nana")
1029        self.assertRaises(ValueError, float, "na")
1030        self.assertRaises(ValueError, float, "+na")
1031        self.assertRaises(ValueError, float, "-na")
1032
1033        self.assertRaises(ValueError, float, "++nan")
1034        self.assertRaises(ValueError, float, "-+NAN")
1035        self.assertRaises(ValueError, float, "+-NaN")
1036        self.assertRaises(ValueError, float, "--nAn")
1037
1038    def test_nan_as_str(self):
1039        self.assertEqual(repr(1e300 * 1e300 * 0), "nan")
1040        self.assertEqual(repr(-1e300 * 1e300 * 0), "nan")
1041
1042        self.assertEqual(str(1e300 * 1e300 * 0), "nan")
1043        self.assertEqual(str(-1e300 * 1e300 * 0), "nan")
1044
1045    def test_inf_signs(self):
1046        self.assertEqual(copysign(1.0, float('inf')), 1.0)
1047        self.assertEqual(copysign(1.0, float('-inf')), -1.0)
1048
1049    def test_nan_signs(self):
1050        # The sign of float('nan') should be predictable.
1051        self.assertEqual(copysign(1.0, float('nan')), 1.0)
1052        self.assertEqual(copysign(1.0, float('-nan')), -1.0)
1053
1054
1055fromHex = float.fromhex
1056toHex = float.hex
1057class HexFloatTestCase(FloatsAreIdenticalMixin, unittest.TestCase):
1058    MAX = fromHex('0x.fffffffffffff8p+1024')  # max normal
1059    MIN = fromHex('0x1p-1022')                # min normal
1060    TINY = fromHex('0x0.0000000000001p-1022') # min subnormal
1061    EPS = fromHex('0x0.0000000000001p0') # diff between 1.0 and next float up
1062
1063    def identical(self, x, y):
1064        self.assertFloatsAreIdentical(x, y)
1065
1066    def test_ends(self):
1067        self.identical(self.MIN, ldexp(1.0, -1022))
1068        self.identical(self.TINY, ldexp(1.0, -1074))
1069        self.identical(self.EPS, ldexp(1.0, -52))
1070        self.identical(self.MAX, 2.*(ldexp(1.0, 1023) - ldexp(1.0, 970)))
1071
1072    def test_invalid_inputs(self):
1073        invalid_inputs = [
1074            'infi',   # misspelt infinities and nans
1075            '-Infinit',
1076            '++inf',
1077            '-+Inf',
1078            '--nan',
1079            '+-NaN',
1080            'snan',
1081            'NaNs',
1082            'nna',
1083            'an',
1084            'nf',
1085            'nfinity',
1086            'inity',
1087            'iinity',
1088            '0xnan',
1089            '',
1090            ' ',
1091            'x1.0p0',
1092            '0xX1.0p0',
1093            '+ 0x1.0p0', # internal whitespace
1094            '- 0x1.0p0',
1095            '0 x1.0p0',
1096            '0x 1.0p0',
1097            '0x1 2.0p0',
1098            '+0x1 .0p0',
1099            '0x1. 0p0',
1100            '-0x1.0 1p0',
1101            '-0x1.0 p0',
1102            '+0x1.0p +0',
1103            '0x1.0p -0',
1104            '0x1.0p 0',
1105            '+0x1.0p+ 0',
1106            '-0x1.0p- 0',
1107            '++0x1.0p-0', # double signs
1108            '--0x1.0p0',
1109            '+-0x1.0p+0',
1110            '-+0x1.0p0',
1111            '0x1.0p++0',
1112            '+0x1.0p+-0',
1113            '-0x1.0p-+0',
1114            '0x1.0p--0',
1115            '0x1.0.p0',
1116            '0x.p0', # no hex digits before or after point
1117            '0x1,p0', # wrong decimal point character
1118            '0x1pa',
1119            '0x1p\uff10',  # fullwidth Unicode digits
1120            '\uff10x1p0',
1121            '0x\uff11p0',
1122            '0x1.\uff10p0',
1123            '0x1p0 \n 0x2p0',
1124            '0x1p0\0 0x1p0',  # embedded null byte is not end of string
1125            ]
1126        for x in invalid_inputs:
1127            try:
1128                result = fromHex(x)
1129            except ValueError:
1130                pass
1131            else:
1132                self.fail('Expected float.fromhex(%r) to raise ValueError; '
1133                          'got %r instead' % (x, result))
1134
1135
1136    def test_whitespace(self):
1137        value_pairs = [
1138            ('inf', INF),
1139            ('-Infinity', -INF),
1140            ('nan', NAN),
1141            ('1.0', 1.0),
1142            ('-0x.2', -0.125),
1143            ('-0.0', -0.0)
1144            ]
1145        whitespace = [
1146            '',
1147            ' ',
1148            '\t',
1149            '\n',
1150            '\n \t',
1151            '\f',
1152            '\v',
1153            '\r'
1154            ]
1155        for inp, expected in value_pairs:
1156            for lead in whitespace:
1157                for trail in whitespace:
1158                    got = fromHex(lead + inp + trail)
1159                    self.identical(got, expected)
1160
1161
1162    def test_from_hex(self):
1163        MIN = self.MIN
1164        MAX = self.MAX
1165        TINY = self.TINY
1166        EPS = self.EPS
1167
1168        # two spellings of infinity, with optional signs; case-insensitive
1169        self.identical(fromHex('inf'), INF)
1170        self.identical(fromHex('+Inf'), INF)
1171        self.identical(fromHex('-INF'), -INF)
1172        self.identical(fromHex('iNf'), INF)
1173        self.identical(fromHex('Infinity'), INF)
1174        self.identical(fromHex('+INFINITY'), INF)
1175        self.identical(fromHex('-infinity'), -INF)
1176        self.identical(fromHex('-iNFiNitY'), -INF)
1177
1178        # nans with optional sign; case insensitive
1179        self.identical(fromHex('nan'), NAN)
1180        self.identical(fromHex('+NaN'), NAN)
1181        self.identical(fromHex('-NaN'), NAN)
1182        self.identical(fromHex('-nAN'), NAN)
1183
1184        # variations in input format
1185        self.identical(fromHex('1'), 1.0)
1186        self.identical(fromHex('+1'), 1.0)
1187        self.identical(fromHex('1.'), 1.0)
1188        self.identical(fromHex('1.0'), 1.0)
1189        self.identical(fromHex('1.0p0'), 1.0)
1190        self.identical(fromHex('01'), 1.0)
1191        self.identical(fromHex('01.'), 1.0)
1192        self.identical(fromHex('0x1'), 1.0)
1193        self.identical(fromHex('0x1.'), 1.0)
1194        self.identical(fromHex('0x1.0'), 1.0)
1195        self.identical(fromHex('+0x1.0'), 1.0)
1196        self.identical(fromHex('0x1p0'), 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('0x1.p0'), 1.0)
1201        self.identical(fromHex('0x1.0p0'), 1.0)
1202        self.identical(fromHex('0x.1p4'), 1.0)
1203        self.identical(fromHex('0x.1p04'), 1.0)
1204        self.identical(fromHex('0x.1p004'), 1.0)
1205        self.identical(fromHex('0x1p+0'), 1.0)
1206        self.identical(fromHex('0x1P-0'), 1.0)
1207        self.identical(fromHex('+0x1p0'), 1.0)
1208        self.identical(fromHex('0x01p0'), 1.0)
1209        self.identical(fromHex('0x1p00'), 1.0)
1210        self.identical(fromHex(' 0x1p0 '), 1.0)
1211        self.identical(fromHex('\n 0x1p0'), 1.0)
1212        self.identical(fromHex('0x1p0 \t'), 1.0)
1213        self.identical(fromHex('0xap0'), 10.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('0xbep0'), 190.0)
1218        self.identical(fromHex('0xBep0'), 190.0)
1219        self.identical(fromHex('0xbEp0'), 190.0)
1220        self.identical(fromHex('0XBE0P-4'), 190.0)
1221        self.identical(fromHex('0xBEp0'), 190.0)
1222        self.identical(fromHex('0xB.Ep4'), 190.0)
1223        self.identical(fromHex('0x.BEp8'), 190.0)
1224        self.identical(fromHex('0x.0BEp12'), 190.0)
1225
1226        # moving the point around
1227        pi = fromHex('0x1.921fb54442d18p1')
1228        self.identical(fromHex('0x.006487ed5110b46p11'), pi)
1229        self.identical(fromHex('0x.00c90fdaa22168cp10'), pi)
1230        self.identical(fromHex('0x.01921fb54442d18p9'), pi)
1231        self.identical(fromHex('0x.03243f6a8885a3p8'), pi)
1232        self.identical(fromHex('0x.06487ed5110b46p7'), pi)
1233        self.identical(fromHex('0x.0c90fdaa22168cp6'), pi)
1234        self.identical(fromHex('0x.1921fb54442d18p5'), pi)
1235        self.identical(fromHex('0x.3243f6a8885a3p4'), pi)
1236        self.identical(fromHex('0x.6487ed5110b46p3'), pi)
1237        self.identical(fromHex('0x.c90fdaa22168cp2'), pi)
1238        self.identical(fromHex('0x1.921fb54442d18p1'), pi)
1239        self.identical(fromHex('0x3.243f6a8885a3p0'), pi)
1240        self.identical(fromHex('0x6.487ed5110b46p-1'), pi)
1241        self.identical(fromHex('0xc.90fdaa22168cp-2'), pi)
1242        self.identical(fromHex('0x19.21fb54442d18p-3'), pi)
1243        self.identical(fromHex('0x32.43f6a8885a3p-4'), pi)
1244        self.identical(fromHex('0x64.87ed5110b46p-5'), pi)
1245        self.identical(fromHex('0xc9.0fdaa22168cp-6'), pi)
1246        self.identical(fromHex('0x192.1fb54442d18p-7'), pi)
1247        self.identical(fromHex('0x324.3f6a8885a3p-8'), pi)
1248        self.identical(fromHex('0x648.7ed5110b46p-9'), pi)
1249        self.identical(fromHex('0xc90.fdaa22168cp-10'), pi)
1250        self.identical(fromHex('0x1921.fb54442d18p-11'), pi)
1251        # ...
1252        self.identical(fromHex('0x1921fb54442d1.8p-47'), pi)
1253        self.identical(fromHex('0x3243f6a8885a3p-48'), pi)
1254        self.identical(fromHex('0x6487ed5110b46p-49'), pi)
1255        self.identical(fromHex('0xc90fdaa22168cp-50'), pi)
1256        self.identical(fromHex('0x1921fb54442d18p-51'), pi)
1257        self.identical(fromHex('0x3243f6a8885a30p-52'), pi)
1258        self.identical(fromHex('0x6487ed5110b460p-53'), pi)
1259        self.identical(fromHex('0xc90fdaa22168c0p-54'), pi)
1260        self.identical(fromHex('0x1921fb54442d180p-55'), pi)
1261
1262
1263        # results that should overflow...
1264        self.assertRaises(OverflowError, fromHex, '-0x1p1024')
1265        self.assertRaises(OverflowError, fromHex, '0x1p+1025')
1266        self.assertRaises(OverflowError, fromHex, '+0X1p1030')
1267        self.assertRaises(OverflowError, fromHex, '-0x1p+1100')
1268        self.assertRaises(OverflowError, fromHex, '0X1p123456789123456789')
1269        self.assertRaises(OverflowError, fromHex, '+0X.8p+1025')
1270        self.assertRaises(OverflowError, fromHex, '+0x0.8p1025')
1271        self.assertRaises(OverflowError, fromHex, '-0x0.4p1026')
1272        self.assertRaises(OverflowError, fromHex, '0X2p+1023')
1273        self.assertRaises(OverflowError, fromHex, '0x2.p1023')
1274        self.assertRaises(OverflowError, fromHex, '-0x2.0p+1023')
1275        self.assertRaises(OverflowError, fromHex, '+0X4p+1022')
1276        self.assertRaises(OverflowError, fromHex, '0x1.ffffffffffffffp+1023')
1277        self.assertRaises(OverflowError, fromHex, '-0X1.fffffffffffff9p1023')
1278        self.assertRaises(OverflowError, fromHex, '0X1.fffffffffffff8p1023')
1279        self.assertRaises(OverflowError, fromHex, '+0x3.fffffffffffffp1022')
1280        self.assertRaises(OverflowError, fromHex, '0x3fffffffffffffp+970')
1281        self.assertRaises(OverflowError, fromHex, '0x10000000000000000p960')
1282        self.assertRaises(OverflowError, fromHex, '-0Xffffffffffffffffp960')
1283
1284        # ...and those that round to +-max float
1285        self.identical(fromHex('+0x1.fffffffffffffp+1023'), MAX)
1286        self.identical(fromHex('-0X1.fffffffffffff7p1023'), -MAX)
1287        self.identical(fromHex('0X1.fffffffffffff7fffffffffffffp1023'), MAX)
1288
1289        # zeros
1290        self.identical(fromHex('0x0p0'), 0.0)
1291        self.identical(fromHex('0x0p1000'), 0.0)
1292        self.identical(fromHex('-0x0p1023'), -0.0)
1293        self.identical(fromHex('0X0p1024'), 0.0)
1294        self.identical(fromHex('-0x0p1025'), -0.0)
1295        self.identical(fromHex('0X0p2000'), 0.0)
1296        self.identical(fromHex('0x0p123456789123456789'), 0.0)
1297        self.identical(fromHex('-0X0p-0'), -0.0)
1298        self.identical(fromHex('-0X0p-1000'), -0.0)
1299        self.identical(fromHex('0x0p-1023'), 0.0)
1300        self.identical(fromHex('-0X0p-1024'), -0.0)
1301        self.identical(fromHex('-0x0p-1025'), -0.0)
1302        self.identical(fromHex('-0x0p-1072'), -0.0)
1303        self.identical(fromHex('0X0p-1073'), 0.0)
1304        self.identical(fromHex('-0x0p-1074'), -0.0)
1305        self.identical(fromHex('0x0p-1075'), 0.0)
1306        self.identical(fromHex('0X0p-1076'), 0.0)
1307        self.identical(fromHex('-0X0p-2000'), -0.0)
1308        self.identical(fromHex('-0x0p-123456789123456789'), -0.0)
1309
1310        # values that should underflow to 0
1311        self.identical(fromHex('0X1p-1075'), 0.0)
1312        self.identical(fromHex('-0X1p-1075'), -0.0)
1313        self.identical(fromHex('-0x1p-123456789123456789'), -0.0)
1314        self.identical(fromHex('0x1.00000000000000001p-1075'), TINY)
1315        self.identical(fromHex('-0x1.1p-1075'), -TINY)
1316        self.identical(fromHex('0x1.fffffffffffffffffp-1075'), TINY)
1317
1318        # check round-half-even is working correctly near 0 ...
1319        self.identical(fromHex('0x1p-1076'), 0.0)
1320        self.identical(fromHex('0X2p-1076'), 0.0)
1321        self.identical(fromHex('0X3p-1076'), TINY)
1322        self.identical(fromHex('0x4p-1076'), TINY)
1323        self.identical(fromHex('0X5p-1076'), TINY)
1324        self.identical(fromHex('0X6p-1076'), 2*TINY)
1325        self.identical(fromHex('0x7p-1076'), 2*TINY)
1326        self.identical(fromHex('0X8p-1076'), 2*TINY)
1327        self.identical(fromHex('0X9p-1076'), 2*TINY)
1328        self.identical(fromHex('0xap-1076'), 2*TINY)
1329        self.identical(fromHex('0Xbp-1076'), 3*TINY)
1330        self.identical(fromHex('0xcp-1076'), 3*TINY)
1331        self.identical(fromHex('0Xdp-1076'), 3*TINY)
1332        self.identical(fromHex('0Xep-1076'), 4*TINY)
1333        self.identical(fromHex('0xfp-1076'), 4*TINY)
1334        self.identical(fromHex('0x10p-1076'), 4*TINY)
1335        self.identical(fromHex('-0x1p-1076'), -0.0)
1336        self.identical(fromHex('-0X2p-1076'), -0.0)
1337        self.identical(fromHex('-0x3p-1076'), -TINY)
1338        self.identical(fromHex('-0X4p-1076'), -TINY)
1339        self.identical(fromHex('-0x5p-1076'), -TINY)
1340        self.identical(fromHex('-0x6p-1076'), -2*TINY)
1341        self.identical(fromHex('-0X7p-1076'), -2*TINY)
1342        self.identical(fromHex('-0X8p-1076'), -2*TINY)
1343        self.identical(fromHex('-0X9p-1076'), -2*TINY)
1344        self.identical(fromHex('-0Xap-1076'), -2*TINY)
1345        self.identical(fromHex('-0xbp-1076'), -3*TINY)
1346        self.identical(fromHex('-0xcp-1076'), -3*TINY)
1347        self.identical(fromHex('-0Xdp-1076'), -3*TINY)
1348        self.identical(fromHex('-0xep-1076'), -4*TINY)
1349        self.identical(fromHex('-0Xfp-1076'), -4*TINY)
1350        self.identical(fromHex('-0X10p-1076'), -4*TINY)
1351
1352        # ... and near MIN ...
1353        self.identical(fromHex('0x0.ffffffffffffd6p-1022'), MIN-3*TINY)
1354        self.identical(fromHex('0x0.ffffffffffffd8p-1022'), MIN-2*TINY)
1355        self.identical(fromHex('0x0.ffffffffffffdap-1022'), MIN-2*TINY)
1356        self.identical(fromHex('0x0.ffffffffffffdcp-1022'), MIN-2*TINY)
1357        self.identical(fromHex('0x0.ffffffffffffdep-1022'), MIN-2*TINY)
1358        self.identical(fromHex('0x0.ffffffffffffe0p-1022'), MIN-2*TINY)
1359        self.identical(fromHex('0x0.ffffffffffffe2p-1022'), MIN-2*TINY)
1360        self.identical(fromHex('0x0.ffffffffffffe4p-1022'), MIN-2*TINY)
1361        self.identical(fromHex('0x0.ffffffffffffe6p-1022'), MIN-2*TINY)
1362        self.identical(fromHex('0x0.ffffffffffffe8p-1022'), MIN-2*TINY)
1363        self.identical(fromHex('0x0.ffffffffffffeap-1022'), MIN-TINY)
1364        self.identical(fromHex('0x0.ffffffffffffecp-1022'), MIN-TINY)
1365        self.identical(fromHex('0x0.ffffffffffffeep-1022'), MIN-TINY)
1366        self.identical(fromHex('0x0.fffffffffffff0p-1022'), MIN-TINY)
1367        self.identical(fromHex('0x0.fffffffffffff2p-1022'), MIN-TINY)
1368        self.identical(fromHex('0x0.fffffffffffff4p-1022'), MIN-TINY)
1369        self.identical(fromHex('0x0.fffffffffffff6p-1022'), MIN-TINY)
1370        self.identical(fromHex('0x0.fffffffffffff8p-1022'), MIN)
1371        self.identical(fromHex('0x0.fffffffffffffap-1022'), MIN)
1372        self.identical(fromHex('0x0.fffffffffffffcp-1022'), MIN)
1373        self.identical(fromHex('0x0.fffffffffffffep-1022'), MIN)
1374        self.identical(fromHex('0x1.00000000000000p-1022'), MIN)
1375        self.identical(fromHex('0x1.00000000000002p-1022'), MIN)
1376        self.identical(fromHex('0x1.00000000000004p-1022'), MIN)
1377        self.identical(fromHex('0x1.00000000000006p-1022'), MIN)
1378        self.identical(fromHex('0x1.00000000000008p-1022'), MIN)
1379        self.identical(fromHex('0x1.0000000000000ap-1022'), MIN+TINY)
1380        self.identical(fromHex('0x1.0000000000000cp-1022'), MIN+TINY)
1381        self.identical(fromHex('0x1.0000000000000ep-1022'), MIN+TINY)
1382        self.identical(fromHex('0x1.00000000000010p-1022'), MIN+TINY)
1383        self.identical(fromHex('0x1.00000000000012p-1022'), MIN+TINY)
1384        self.identical(fromHex('0x1.00000000000014p-1022'), MIN+TINY)
1385        self.identical(fromHex('0x1.00000000000016p-1022'), MIN+TINY)
1386        self.identical(fromHex('0x1.00000000000018p-1022'), MIN+2*TINY)
1387
1388        # ... and near 1.0.
1389        self.identical(fromHex('0x0.fffffffffffff0p0'), 1.0-EPS)
1390        self.identical(fromHex('0x0.fffffffffffff1p0'), 1.0-EPS)
1391        self.identical(fromHex('0X0.fffffffffffff2p0'), 1.0-EPS)
1392        self.identical(fromHex('0x0.fffffffffffff3p0'), 1.0-EPS)
1393        self.identical(fromHex('0X0.fffffffffffff4p0'), 1.0-EPS)
1394        self.identical(fromHex('0X0.fffffffffffff5p0'), 1.0-EPS/2)
1395        self.identical(fromHex('0X0.fffffffffffff6p0'), 1.0-EPS/2)
1396        self.identical(fromHex('0x0.fffffffffffff7p0'), 1.0-EPS/2)
1397        self.identical(fromHex('0x0.fffffffffffff8p0'), 1.0-EPS/2)
1398        self.identical(fromHex('0X0.fffffffffffff9p0'), 1.0-EPS/2)
1399        self.identical(fromHex('0X0.fffffffffffffap0'), 1.0-EPS/2)
1400        self.identical(fromHex('0x0.fffffffffffffbp0'), 1.0-EPS/2)
1401        self.identical(fromHex('0X0.fffffffffffffcp0'), 1.0)
1402        self.identical(fromHex('0x0.fffffffffffffdp0'), 1.0)
1403        self.identical(fromHex('0X0.fffffffffffffep0'), 1.0)
1404        self.identical(fromHex('0x0.ffffffffffffffp0'), 1.0)
1405        self.identical(fromHex('0X1.00000000000000p0'), 1.0)
1406        self.identical(fromHex('0X1.00000000000001p0'), 1.0)
1407        self.identical(fromHex('0x1.00000000000002p0'), 1.0)
1408        self.identical(fromHex('0X1.00000000000003p0'), 1.0)
1409        self.identical(fromHex('0x1.00000000000004p0'), 1.0)
1410        self.identical(fromHex('0X1.00000000000005p0'), 1.0)
1411        self.identical(fromHex('0X1.00000000000006p0'), 1.0)
1412        self.identical(fromHex('0X1.00000000000007p0'), 1.0)
1413        self.identical(fromHex('0x1.00000000000007ffffffffffffffffffffp0'),
1414                       1.0)
1415        self.identical(fromHex('0x1.00000000000008p0'), 1.0)
1416        self.identical(fromHex('0x1.00000000000008000000000000000001p0'),
1417                       1+EPS)
1418        self.identical(fromHex('0X1.00000000000009p0'), 1.0+EPS)
1419        self.identical(fromHex('0x1.0000000000000ap0'), 1.0+EPS)
1420        self.identical(fromHex('0x1.0000000000000bp0'), 1.0+EPS)
1421        self.identical(fromHex('0X1.0000000000000cp0'), 1.0+EPS)
1422        self.identical(fromHex('0x1.0000000000000dp0'), 1.0+EPS)
1423        self.identical(fromHex('0x1.0000000000000ep0'), 1.0+EPS)
1424        self.identical(fromHex('0X1.0000000000000fp0'), 1.0+EPS)
1425        self.identical(fromHex('0x1.00000000000010p0'), 1.0+EPS)
1426        self.identical(fromHex('0X1.00000000000011p0'), 1.0+EPS)
1427        self.identical(fromHex('0x1.00000000000012p0'), 1.0+EPS)
1428        self.identical(fromHex('0X1.00000000000013p0'), 1.0+EPS)
1429        self.identical(fromHex('0X1.00000000000014p0'), 1.0+EPS)
1430        self.identical(fromHex('0x1.00000000000015p0'), 1.0+EPS)
1431        self.identical(fromHex('0x1.00000000000016p0'), 1.0+EPS)
1432        self.identical(fromHex('0X1.00000000000017p0'), 1.0+EPS)
1433        self.identical(fromHex('0x1.00000000000017ffffffffffffffffffffp0'),
1434                       1.0+EPS)
1435        self.identical(fromHex('0x1.00000000000018p0'), 1.0+2*EPS)
1436        self.identical(fromHex('0X1.00000000000018000000000000000001p0'),
1437                       1.0+2*EPS)
1438        self.identical(fromHex('0x1.00000000000019p0'), 1.0+2*EPS)
1439        self.identical(fromHex('0X1.0000000000001ap0'), 1.0+2*EPS)
1440        self.identical(fromHex('0X1.0000000000001bp0'), 1.0+2*EPS)
1441        self.identical(fromHex('0x1.0000000000001cp0'), 1.0+2*EPS)
1442        self.identical(fromHex('0x1.0000000000001dp0'), 1.0+2*EPS)
1443        self.identical(fromHex('0x1.0000000000001ep0'), 1.0+2*EPS)
1444        self.identical(fromHex('0X1.0000000000001fp0'), 1.0+2*EPS)
1445        self.identical(fromHex('0x1.00000000000020p0'), 1.0+2*EPS)
1446
1447        # Regression test for a corner-case bug reported in b.p.o. 44954
1448        self.identical(fromHex('0x.8p-1074'), 0.0)
1449        self.identical(fromHex('0x.80p-1074'), 0.0)
1450        self.identical(fromHex('0x.81p-1074'), TINY)
1451        self.identical(fromHex('0x8p-1078'), 0.0)
1452        self.identical(fromHex('0x8.0p-1078'), 0.0)
1453        self.identical(fromHex('0x8.1p-1078'), TINY)
1454        self.identical(fromHex('0x80p-1082'), 0.0)
1455        self.identical(fromHex('0x81p-1082'), TINY)
1456        self.identical(fromHex('.8p-1074'), 0.0)
1457        self.identical(fromHex('8p-1078'), 0.0)
1458        self.identical(fromHex('-.8p-1074'), -0.0)
1459        self.identical(fromHex('+8p-1078'), 0.0)
1460
1461    def test_roundtrip(self):
1462        def roundtrip(x):
1463            return fromHex(toHex(x))
1464
1465        for x in [NAN, INF, self.MAX, self.MIN, self.MIN-self.TINY, self.TINY, 0.0]:
1466            self.identical(x, roundtrip(x))
1467            self.identical(-x, roundtrip(-x))
1468
1469        # fromHex(toHex(x)) should exactly recover x, for any non-NaN float x.
1470        import random
1471        for i in range(10000):
1472            e = random.randrange(-1200, 1200)
1473            m = random.random()
1474            s = random.choice([1.0, -1.0])
1475            try:
1476                x = s*ldexp(m, e)
1477            except OverflowError:
1478                pass
1479            else:
1480                self.identical(x, fromHex(toHex(x)))
1481
1482    def test_subclass(self):
1483        class F(float):
1484            def __new__(cls, value):
1485                return float.__new__(cls, value + 1)
1486
1487        f = F.fromhex((1.5).hex())
1488        self.assertIs(type(f), F)
1489        self.assertEqual(f, 2.5)
1490
1491        class F2(float):
1492            def __init__(self, value):
1493                self.foo = 'bar'
1494
1495        f = F2.fromhex((1.5).hex())
1496        self.assertIs(type(f), F2)
1497        self.assertEqual(f, 1.5)
1498        self.assertEqual(getattr(f, 'foo', 'none'), 'bar')
1499
1500
1501if __name__ == '__main__':
1502    unittest.main()
1503