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