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