2
import unittest, struct
4
from test import support
6
from math import isinf, isnan, copysign, ldexp
8
import random, fractions
13
class GeneralFloatCases(unittest.TestCase):
16
self.assertEqual(float(3.14), 3.14)
17
self.assertEqual(float(314), 314.0)
18
self.assertEqual(float(" 3.14 "), 3.14)
19
self.assertEqual(float(b" 3.14 "), 3.14)
20
self.assertRaises(ValueError, float, " 0x3.1 ")
21
self.assertRaises(ValueError, float, " -0x3.p-1 ")
22
self.assertRaises(ValueError, float, " +0x3.p-1 ")
23
self.assertRaises(ValueError, float, "++3.14")
24
self.assertRaises(ValueError, float, "+-3.14")
25
self.assertRaises(ValueError, float, "-+3.14")
26
self.assertRaises(ValueError, float, "--3.14")
27
self.assertEqual(float(b" \u0663.\u0661\u0664 ".decode('raw-unicode-escape')), 3.14)
29
@support.run_with_locale('LC_NUMERIC', 'fr_FR', 'de_DE')
30
def test_float_with_comma(self):
31
# set locale to something that doesn't use '.' for the decimal point
32
# float must not accept the locale specific decimal point but
33
# it still has to accept the normal python syntac
35
if not locale.localeconv()['decimal_point'] == ',':
38
self.assertEqual(float(" 3.14 "), 3.14)
39
self.assertEqual(float("+3.14 "), 3.14)
40
self.assertEqual(float("-3.14 "), -3.14)
41
self.assertEqual(float(".14 "), .14)
42
self.assertEqual(float("3. "), 3.0)
43
self.assertEqual(float("3.e3 "), 3000.0)
44
self.assertEqual(float("3.2e3 "), 3200.0)
45
self.assertEqual(float("2.5e-1 "), 0.25)
46
self.assertEqual(float("5e-1"), 0.5)
47
self.assertRaises(ValueError, float, " 3,14 ")
48
self.assertRaises(ValueError, float, " +3,14 ")
49
self.assertRaises(ValueError, float, " -3,14 ")
50
self.assertRaises(ValueError, float, " 0x3.1 ")
51
self.assertRaises(ValueError, float, " -0x3.p-1 ")
52
self.assertRaises(ValueError, float, " +0x3.p-1 ")
53
self.assertEqual(float(" 25.e-1 "), 2.5)
54
self.assertEqual(support.fcmp(float(" .25e-1 "), .025), 0)
56
def test_floatconversion(self):
57
# Make sure that calls to __float__() work properly
71
def __new__(cls, value=0.):
72
return float.__new__(cls, 2*value)
81
self.assertAlmostEqual(float(Foo0()), 42.)
82
self.assertAlmostEqual(float(Foo1()), 42.)
83
self.assertAlmostEqual(float(Foo2()), 42.)
84
self.assertAlmostEqual(float(Foo3(21)), 42.)
85
self.assertRaises(TypeError, float, Foo4(42))
87
def test_floatasratio(self):
94
self.assertEqual(f.as_integer_ratio(), ratio)
96
for i in range(10000):
98
f *= 10 ** random.randint(-100, 100)
99
n, d = f.as_integer_ratio()
100
self.assertEqual(float(n).__truediv__(d), f)
102
R = fractions.Fraction
103
self.assertEqual(R(0, 1),
104
R(*float(0.0).as_integer_ratio()))
105
self.assertEqual(R(5, 2),
106
R(*float(2.5).as_integer_ratio()))
107
self.assertEqual(R(1, 2),
108
R(*float(0.5).as_integer_ratio()))
109
self.assertEqual(R(4728779608739021, 2251799813685248),
110
R(*float(2.1).as_integer_ratio()))
111
self.assertEqual(R(-4728779608739021, 2251799813685248),
112
R(*float(-2.1).as_integer_ratio()))
113
self.assertEqual(R(-2100, 1),
114
R(*float(-2100.0).as_integer_ratio()))
116
self.assertRaises(OverflowError, float('inf').as_integer_ratio)
117
self.assertRaises(OverflowError, float('-inf').as_integer_ratio)
118
self.assertRaises(ValueError, float('nan').as_integer_ratio)
120
def test_float_containment(self):
121
floats = (INF, -INF, 0.0, 1.0, NAN)
123
self.assert_(f in [f], "'%r' not in []" % f)
124
self.assert_(f in (f,), "'%r' not in ()" % f)
125
self.assert_(f in {f}, "'%r' not in set()" % f)
126
self.assert_(f in {f: None}, "'%r' not in {}" % f)
127
self.assertEqual([f].count(f), 1, "[].count('%r') != 1" % f)
128
self.assert_(f in floats, "'%r' not in container" % f)
131
# nonidentical containers, same type, same contents
132
self.assert_([f] == [f], "[%r] != [%r]" % (f, f))
133
self.assert_((f,) == (f,), "(%r,) != (%r,)" % (f, f))
134
self.assert_({f} == {f}, "{%r} != {%r}" % (f, f))
135
self.assert_({f : None} == {f: None}, "{%r : None} != "
136
"{%r : None}" % (f, f))
138
# identical containers
139
l, t, s, d = [f], (f,), {f}, {f: None}
140
self.assert_(l == l, "[%r] not equal to itself" % f)
141
self.assert_(t == t, "(%r,) not equal to itself" % f)
142
self.assert_(s == s, "{%r} not equal to itself" % f)
143
self.assert_(d == d, "{%r : None} not equal to itself" % f)
147
class FormatFunctionsTestCase(unittest.TestCase):
150
self.save_formats = {'double':float.__getformat__('double'),
151
'float':float.__getformat__('float')}
154
float.__setformat__('double', self.save_formats['double'])
155
float.__setformat__('float', self.save_formats['float'])
157
def test_getformat(self):
158
self.assert_(float.__getformat__('double') in
159
['unknown', 'IEEE, big-endian', 'IEEE, little-endian'])
160
self.assert_(float.__getformat__('float') in
161
['unknown', 'IEEE, big-endian', 'IEEE, little-endian'])
162
self.assertRaises(ValueError, float.__getformat__, 'chicken')
163
self.assertRaises(TypeError, float.__getformat__, 1)
165
def test_setformat(self):
166
for t in 'double', 'float':
167
float.__setformat__(t, 'unknown')
168
if self.save_formats[t] == 'IEEE, big-endian':
169
self.assertRaises(ValueError, float.__setformat__,
170
t, 'IEEE, little-endian')
171
elif self.save_formats[t] == 'IEEE, little-endian':
172
self.assertRaises(ValueError, float.__setformat__,
173
t, 'IEEE, big-endian')
175
self.assertRaises(ValueError, float.__setformat__,
176
t, 'IEEE, big-endian')
177
self.assertRaises(ValueError, float.__setformat__,
178
t, 'IEEE, little-endian')
179
self.assertRaises(ValueError, float.__setformat__,
181
self.assertRaises(ValueError, float.__setformat__,
182
'chicken', 'unknown')
184
BE_DOUBLE_INF = b'\x7f\xf0\x00\x00\x00\x00\x00\x00'
185
LE_DOUBLE_INF = bytes(reversed(BE_DOUBLE_INF))
186
BE_DOUBLE_NAN = b'\x7f\xf8\x00\x00\x00\x00\x00\x00'
187
LE_DOUBLE_NAN = bytes(reversed(BE_DOUBLE_NAN))
189
BE_FLOAT_INF = b'\x7f\x80\x00\x00'
190
LE_FLOAT_INF = bytes(reversed(BE_FLOAT_INF))
191
BE_FLOAT_NAN = b'\x7f\xc0\x00\x00'
192
LE_FLOAT_NAN = bytes(reversed(BE_FLOAT_NAN))
194
# on non-IEEE platforms, attempting to unpack a bit pattern
195
# representing an infinity or a NaN should raise an exception.
197
class UnknownFormatTestCase(unittest.TestCase):
199
self.save_formats = {'double':float.__getformat__('double'),
200
'float':float.__getformat__('float')}
201
float.__setformat__('double', 'unknown')
202
float.__setformat__('float', 'unknown')
205
float.__setformat__('double', self.save_formats['double'])
206
float.__setformat__('float', self.save_formats['float'])
208
def test_double_specials_dont_unpack(self):
209
for fmt, data in [('>d', BE_DOUBLE_INF),
210
('>d', BE_DOUBLE_NAN),
211
('<d', LE_DOUBLE_INF),
212
('<d', LE_DOUBLE_NAN)]:
213
self.assertRaises(ValueError, struct.unpack, fmt, data)
215
def test_float_specials_dont_unpack(self):
216
for fmt, data in [('>f', BE_FLOAT_INF),
217
('>f', BE_FLOAT_NAN),
218
('<f', LE_FLOAT_INF),
219
('<f', LE_FLOAT_NAN)]:
220
self.assertRaises(ValueError, struct.unpack, fmt, data)
223
# on an IEEE platform, all we guarantee is that bit patterns
224
# representing infinities or NaNs do not raise an exception; all else
225
# is accident (today).
226
# let's also try to guarantee that -0.0 and 0.0 don't get confused.
228
class IEEEFormatTestCase(unittest.TestCase):
229
if float.__getformat__("double").startswith("IEEE"):
230
def test_double_specials_do_unpack(self):
231
for fmt, data in [('>d', BE_DOUBLE_INF),
232
('>d', BE_DOUBLE_NAN),
233
('<d', LE_DOUBLE_INF),
234
('<d', LE_DOUBLE_NAN)]:
235
struct.unpack(fmt, data)
237
if float.__getformat__("float").startswith("IEEE"):
238
def test_float_specials_do_unpack(self):
239
for fmt, data in [('>f', BE_FLOAT_INF),
240
('>f', BE_FLOAT_NAN),
241
('<f', LE_FLOAT_INF),
242
('<f', LE_FLOAT_NAN)]:
243
struct.unpack(fmt, data)
245
if float.__getformat__("double").startswith("IEEE"):
246
def test_negative_zero(self):
249
return 0.0, math.atan2(0.0, -1)
251
return 0.0, math.atan2(-0.0, -1)
253
return -0.0, math.atan2(0.0, -1)
255
return -0.0, math.atan2(-0.0, -1)
256
self.assertEquals(pos_pos(), neg_pos())
257
self.assertEquals(pos_neg(), neg_neg())
259
class FormatTestCase(unittest.TestCase):
260
def test_format(self):
261
# these should be rewritten to use both format(x, spec) and
264
self.assertEqual(format(0.0, 'f'), '0.000000')
266
# the default is 'g', except for empty format spec
267
self.assertEqual(format(0.0, ''), '0.0')
268
self.assertEqual(format(0.01, ''), '0.01')
269
self.assertEqual(format(0.01, 'g'), '0.01')
272
self.assertEqual(format(1.0, 'f'), '1.000000')
274
self.assertEqual(format(-1.0, 'f'), '-1.000000')
276
self.assertEqual(format( 1.0, ' f'), ' 1.000000')
277
self.assertEqual(format(-1.0, ' f'), '-1.000000')
278
self.assertEqual(format( 1.0, '+f'), '+1.000000')
279
self.assertEqual(format(-1.0, '+f'), '-1.000000')
282
self.assertEqual(format(-1.0, '%'), '-100.000000%')
284
# conversion to string should fail
285
self.assertRaises(ValueError, format, 3.0, "s")
287
# other format specifiers shouldn't work on floats,
288
# in particular int specifiers
289
for format_spec in ([chr(x) for x in range(ord('a'), ord('z')+1)] +
290
[chr(x) for x in range(ord('A'), ord('Z')+1)]):
291
if not format_spec in 'eEfFgGn%':
292
self.assertRaises(ValueError, format, 0.0, format_spec)
293
self.assertRaises(ValueError, format, 1.0, format_spec)
294
self.assertRaises(ValueError, format, -1.0, format_spec)
295
self.assertRaises(ValueError, format, 1e100, format_spec)
296
self.assertRaises(ValueError, format, -1e100, format_spec)
297
self.assertRaises(ValueError, format, 1e-100, format_spec)
298
self.assertRaises(ValueError, format, -1e-100, format_spec)
300
class ReprTestCase(unittest.TestCase):
302
floats_file = open(os.path.join(os.path.split(__file__)[0],
303
'floating_points.txt'))
304
for line in floats_file:
306
if not line or line.startswith('#'):
309
self.assertEqual(v, eval(repr(v)))
312
# Beginning with Python 2.6 float has cross platform compatible
313
# ways to create and represent inf and nan
314
class InfNanTest(unittest.TestCase):
315
def test_inf_from_str(self):
316
self.assert_(isinf(float("inf")))
317
self.assert_(isinf(float("+inf")))
318
self.assert_(isinf(float("-inf")))
319
self.assert_(isinf(float("infinity")))
320
self.assert_(isinf(float("+infinity")))
321
self.assert_(isinf(float("-infinity")))
323
self.assertEqual(repr(float("inf")), "inf")
324
self.assertEqual(repr(float("+inf")), "inf")
325
self.assertEqual(repr(float("-inf")), "-inf")
326
self.assertEqual(repr(float("infinity")), "inf")
327
self.assertEqual(repr(float("+infinity")), "inf")
328
self.assertEqual(repr(float("-infinity")), "-inf")
330
self.assertEqual(repr(float("INF")), "inf")
331
self.assertEqual(repr(float("+Inf")), "inf")
332
self.assertEqual(repr(float("-iNF")), "-inf")
333
self.assertEqual(repr(float("Infinity")), "inf")
334
self.assertEqual(repr(float("+iNfInItY")), "inf")
335
self.assertEqual(repr(float("-INFINITY")), "-inf")
337
self.assertEqual(str(float("inf")), "inf")
338
self.assertEqual(str(float("+inf")), "inf")
339
self.assertEqual(str(float("-inf")), "-inf")
340
self.assertEqual(str(float("infinity")), "inf")
341
self.assertEqual(str(float("+infinity")), "inf")
342
self.assertEqual(str(float("-infinity")), "-inf")
344
self.assertRaises(ValueError, float, "info")
345
self.assertRaises(ValueError, float, "+info")
346
self.assertRaises(ValueError, float, "-info")
347
self.assertRaises(ValueError, float, "in")
348
self.assertRaises(ValueError, float, "+in")
349
self.assertRaises(ValueError, float, "-in")
350
self.assertRaises(ValueError, float, "infinit")
351
self.assertRaises(ValueError, float, "+Infin")
352
self.assertRaises(ValueError, float, "-INFI")
353
self.assertRaises(ValueError, float, "infinitys")
355
def test_inf_as_str(self):
356
self.assertEqual(repr(1e300 * 1e300), "inf")
357
self.assertEqual(repr(-1e300 * 1e300), "-inf")
359
self.assertEqual(str(1e300 * 1e300), "inf")
360
self.assertEqual(str(-1e300 * 1e300), "-inf")
362
def test_nan_from_str(self):
363
self.assert_(isnan(float("nan")))
364
self.assert_(isnan(float("+nan")))
365
self.assert_(isnan(float("-nan")))
367
self.assertEqual(repr(float("nan")), "nan")
368
self.assertEqual(repr(float("+nan")), "nan")
369
self.assertEqual(repr(float("-nan")), "nan")
371
self.assertEqual(repr(float("NAN")), "nan")
372
self.assertEqual(repr(float("+NAn")), "nan")
373
self.assertEqual(repr(float("-NaN")), "nan")
375
self.assertEqual(str(float("nan")), "nan")
376
self.assertEqual(str(float("+nan")), "nan")
377
self.assertEqual(str(float("-nan")), "nan")
379
self.assertRaises(ValueError, float, "nana")
380
self.assertRaises(ValueError, float, "+nana")
381
self.assertRaises(ValueError, float, "-nana")
382
self.assertRaises(ValueError, float, "na")
383
self.assertRaises(ValueError, float, "+na")
384
self.assertRaises(ValueError, float, "-na")
386
def test_nan_as_str(self):
387
self.assertEqual(repr(1e300 * 1e300 * 0), "nan")
388
self.assertEqual(repr(-1e300 * 1e300 * 0), "nan")
390
self.assertEqual(str(1e300 * 1e300 * 0), "nan")
391
self.assertEqual(str(-1e300 * 1e300 * 0), "nan")
393
def notest_float_nan(self):
394
self.assert_(NAN.is_nan())
395
self.failIf(INF.is_nan())
396
self.failIf((0.).is_nan())
398
def notest_float_inf(self):
399
self.assert_(INF.is_inf())
400
self.failIf(NAN.is_inf())
401
self.failIf((0.).is_inf())
403
fromHex = float.fromhex
405
class HexFloatTestCase(unittest.TestCase):
406
MAX = fromHex('0x.fffffffffffff8p+1024') # max normal
407
MIN = fromHex('0x1p-1022') # min normal
408
TINY = fromHex('0x0.0000000000001p-1022') # min subnormal
409
EPS = fromHex('0x0.0000000000001p0') # diff between 1.0 and next float up
411
def identical(self, x, y):
412
# check that floats x and y are identical, or that both
414
if isnan(x) or isnan(y):
415
if isnan(x) == isnan(y):
417
elif x == y and (x != 0.0 or copysign(1.0, x) == copysign(1.0, y)):
419
self.fail('%r not identical to %r' % (x, y))
422
self.identical(self.MIN, ldexp(1.0, -1022))
423
self.identical(self.TINY, ldexp(1.0, -1074))
424
self.identical(self.EPS, ldexp(1.0, -52))
425
self.identical(self.MAX, 2.*(ldexp(1.0, 1023) - ldexp(1.0, 970)))
427
def test_invalid_inputs(self):
429
'infi', # misspelt infinities and nans
443
'+ 0x1.0p0', # internal whitespace
457
'++0x1.0p-0', # double signs
466
'0x.p0', # no hex digits before or after point
467
'0x1,p0', # wrong decimal point character
469
'0x1p\uff10', # fullwidth Unicode digits
474
'0x1p0\0 0x1p0', # embedded null byte is not end of string
476
for x in invalid_inputs:
482
self.fail('Expected float.fromhex(%r) to raise ValueError; '
483
'got %r instead' % (x, result))
486
def test_from_hex(self):
492
# two spellings of infinity, with optional signs; case-insensitive
493
self.identical(fromHex('inf'), INF)
494
self.identical(fromHex('+Inf'), INF)
495
self.identical(fromHex('-INF'), -INF)
496
self.identical(fromHex('iNf'), INF)
497
self.identical(fromHex('Infinity'), INF)
498
self.identical(fromHex('+INFINITY'), INF)
499
self.identical(fromHex('-infinity'), -INF)
500
self.identical(fromHex('-iNFiNitY'), -INF)
502
# nans with optional sign; case insensitive
503
self.identical(fromHex('nan'), NAN)
504
self.identical(fromHex('+NaN'), NAN)
505
self.identical(fromHex('-NaN'), NAN)
506
self.identical(fromHex('-nAN'), NAN)
508
# variations in input format
509
self.identical(fromHex('1'), 1.0)
510
self.identical(fromHex('+1'), 1.0)
511
self.identical(fromHex('1.'), 1.0)
512
self.identical(fromHex('1.0'), 1.0)
513
self.identical(fromHex('1.0p0'), 1.0)
514
self.identical(fromHex('01'), 1.0)
515
self.identical(fromHex('01.'), 1.0)
516
self.identical(fromHex('0x1'), 1.0)
517
self.identical(fromHex('0x1.'), 1.0)
518
self.identical(fromHex('0x1.0'), 1.0)
519
self.identical(fromHex('+0x1.0'), 1.0)
520
self.identical(fromHex('0x1p0'), 1.0)
521
self.identical(fromHex('0X1p0'), 1.0)
522
self.identical(fromHex('0X1P0'), 1.0)
523
self.identical(fromHex('0x1P0'), 1.0)
524
self.identical(fromHex('0x1.p0'), 1.0)
525
self.identical(fromHex('0x1.0p0'), 1.0)
526
self.identical(fromHex('0x.1p4'), 1.0)
527
self.identical(fromHex('0x.1p04'), 1.0)
528
self.identical(fromHex('0x.1p004'), 1.0)
529
self.identical(fromHex('0x1p+0'), 1.0)
530
self.identical(fromHex('0x1P-0'), 1.0)
531
self.identical(fromHex('+0x1p0'), 1.0)
532
self.identical(fromHex('0x01p0'), 1.0)
533
self.identical(fromHex('0x1p00'), 1.0)
534
self.identical(fromHex(' 0x1p0 '), 1.0)
535
self.identical(fromHex('\n 0x1p0'), 1.0)
536
self.identical(fromHex('0x1p0 \t'), 1.0)
537
self.identical(fromHex('0xap0'), 10.0)
538
self.identical(fromHex('0xAp0'), 10.0)
539
self.identical(fromHex('0xaP0'), 10.0)
540
self.identical(fromHex('0xAP0'), 10.0)
541
self.identical(fromHex('0xbep0'), 190.0)
542
self.identical(fromHex('0xBep0'), 190.0)
543
self.identical(fromHex('0xbEp0'), 190.0)
544
self.identical(fromHex('0XBE0P-4'), 190.0)
545
self.identical(fromHex('0xBEp0'), 190.0)
546
self.identical(fromHex('0xB.Ep4'), 190.0)
547
self.identical(fromHex('0x.BEp8'), 190.0)
548
self.identical(fromHex('0x.0BEp12'), 190.0)
550
# moving the point around
551
pi = fromHex('0x1.921fb54442d18p1')
552
self.identical(fromHex('0x.006487ed5110b46p11'), pi)
553
self.identical(fromHex('0x.00c90fdaa22168cp10'), pi)
554
self.identical(fromHex('0x.01921fb54442d18p9'), pi)
555
self.identical(fromHex('0x.03243f6a8885a3p8'), pi)
556
self.identical(fromHex('0x.06487ed5110b46p7'), pi)
557
self.identical(fromHex('0x.0c90fdaa22168cp6'), pi)
558
self.identical(fromHex('0x.1921fb54442d18p5'), pi)
559
self.identical(fromHex('0x.3243f6a8885a3p4'), pi)
560
self.identical(fromHex('0x.6487ed5110b46p3'), pi)
561
self.identical(fromHex('0x.c90fdaa22168cp2'), pi)
562
self.identical(fromHex('0x1.921fb54442d18p1'), pi)
563
self.identical(fromHex('0x3.243f6a8885a3p0'), pi)
564
self.identical(fromHex('0x6.487ed5110b46p-1'), pi)
565
self.identical(fromHex('0xc.90fdaa22168cp-2'), pi)
566
self.identical(fromHex('0x19.21fb54442d18p-3'), pi)
567
self.identical(fromHex('0x32.43f6a8885a3p-4'), pi)
568
self.identical(fromHex('0x64.87ed5110b46p-5'), pi)
569
self.identical(fromHex('0xc9.0fdaa22168cp-6'), pi)
570
self.identical(fromHex('0x192.1fb54442d18p-7'), pi)
571
self.identical(fromHex('0x324.3f6a8885a3p-8'), pi)
572
self.identical(fromHex('0x648.7ed5110b46p-9'), pi)
573
self.identical(fromHex('0xc90.fdaa22168cp-10'), pi)
574
self.identical(fromHex('0x1921.fb54442d18p-11'), pi)
576
self.identical(fromHex('0x1921fb54442d1.8p-47'), pi)
577
self.identical(fromHex('0x3243f6a8885a3p-48'), pi)
578
self.identical(fromHex('0x6487ed5110b46p-49'), pi)
579
self.identical(fromHex('0xc90fdaa22168cp-50'), pi)
580
self.identical(fromHex('0x1921fb54442d18p-51'), pi)
581
self.identical(fromHex('0x3243f6a8885a30p-52'), pi)
582
self.identical(fromHex('0x6487ed5110b460p-53'), pi)
583
self.identical(fromHex('0xc90fdaa22168c0p-54'), pi)
584
self.identical(fromHex('0x1921fb54442d180p-55'), pi)
587
# results that should overflow...
588
self.assertRaises(OverflowError, fromHex, '-0x1p1024')
589
self.assertRaises(OverflowError, fromHex, '0x1p+1025')
590
self.assertRaises(OverflowError, fromHex, '+0X1p1030')
591
self.assertRaises(OverflowError, fromHex, '-0x1p+1100')
592
self.assertRaises(OverflowError, fromHex, '0X1p123456789123456789')
593
self.assertRaises(OverflowError, fromHex, '+0X.8p+1025')
594
self.assertRaises(OverflowError, fromHex, '+0x0.8p1025')
595
self.assertRaises(OverflowError, fromHex, '-0x0.4p1026')
596
self.assertRaises(OverflowError, fromHex, '0X2p+1023')
597
self.assertRaises(OverflowError, fromHex, '0x2.p1023')
598
self.assertRaises(OverflowError, fromHex, '-0x2.0p+1023')
599
self.assertRaises(OverflowError, fromHex, '+0X4p+1022')
600
self.assertRaises(OverflowError, fromHex, '0x1.ffffffffffffffp+1023')
601
self.assertRaises(OverflowError, fromHex, '-0X1.fffffffffffff9p1023')
602
self.assertRaises(OverflowError, fromHex, '0X1.fffffffffffff8p1023')
603
self.assertRaises(OverflowError, fromHex, '+0x3.fffffffffffffp1022')
604
self.assertRaises(OverflowError, fromHex, '0x3fffffffffffffp+970')
605
self.assertRaises(OverflowError, fromHex, '0x10000000000000000p960')
606
self.assertRaises(OverflowError, fromHex, '-0Xffffffffffffffffp960')
608
# ...and those that round to +-max float
609
self.identical(fromHex('+0x1.fffffffffffffp+1023'), MAX)
610
self.identical(fromHex('-0X1.fffffffffffff7p1023'), -MAX)
611
self.identical(fromHex('0X1.fffffffffffff7fffffffffffffp1023'), MAX)
614
self.identical(fromHex('0x0p0'), 0.0)
615
self.identical(fromHex('0x0p1000'), 0.0)
616
self.identical(fromHex('-0x0p1023'), -0.0)
617
self.identical(fromHex('0X0p1024'), 0.0)
618
self.identical(fromHex('-0x0p1025'), -0.0)
619
self.identical(fromHex('0X0p2000'), 0.0)
620
self.identical(fromHex('0x0p123456789123456789'), 0.0)
621
self.identical(fromHex('-0X0p-0'), -0.0)
622
self.identical(fromHex('-0X0p-1000'), -0.0)
623
self.identical(fromHex('0x0p-1023'), 0.0)
624
self.identical(fromHex('-0X0p-1024'), -0.0)
625
self.identical(fromHex('-0x0p-1025'), -0.0)
626
self.identical(fromHex('-0x0p-1072'), -0.0)
627
self.identical(fromHex('0X0p-1073'), 0.0)
628
self.identical(fromHex('-0x0p-1074'), -0.0)
629
self.identical(fromHex('0x0p-1075'), 0.0)
630
self.identical(fromHex('0X0p-1076'), 0.0)
631
self.identical(fromHex('-0X0p-2000'), -0.0)
632
self.identical(fromHex('-0x0p-123456789123456789'), -0.0)
634
# values that should underflow to 0
635
self.identical(fromHex('0X1p-1075'), 0.0)
636
self.identical(fromHex('-0X1p-1075'), -0.0)
637
self.identical(fromHex('-0x1p-123456789123456789'), -0.0)
638
self.identical(fromHex('0x1.00000000000000001p-1075'), TINY)
639
self.identical(fromHex('-0x1.1p-1075'), -TINY)
640
self.identical(fromHex('0x1.fffffffffffffffffp-1075'), TINY)
642
# check round-half-even is working correctly near 0 ...
643
self.identical(fromHex('0x1p-1076'), 0.0)
644
self.identical(fromHex('0X2p-1076'), 0.0)
645
self.identical(fromHex('0X3p-1076'), TINY)
646
self.identical(fromHex('0x4p-1076'), TINY)
647
self.identical(fromHex('0X5p-1076'), TINY)
648
self.identical(fromHex('0X6p-1076'), 2*TINY)
649
self.identical(fromHex('0x7p-1076'), 2*TINY)
650
self.identical(fromHex('0X8p-1076'), 2*TINY)
651
self.identical(fromHex('0X9p-1076'), 2*TINY)
652
self.identical(fromHex('0xap-1076'), 2*TINY)
653
self.identical(fromHex('0Xbp-1076'), 3*TINY)
654
self.identical(fromHex('0xcp-1076'), 3*TINY)
655
self.identical(fromHex('0Xdp-1076'), 3*TINY)
656
self.identical(fromHex('0Xep-1076'), 4*TINY)
657
self.identical(fromHex('0xfp-1076'), 4*TINY)
658
self.identical(fromHex('0x10p-1076'), 4*TINY)
659
self.identical(fromHex('-0x1p-1076'), -0.0)
660
self.identical(fromHex('-0X2p-1076'), -0.0)
661
self.identical(fromHex('-0x3p-1076'), -TINY)
662
self.identical(fromHex('-0X4p-1076'), -TINY)
663
self.identical(fromHex('-0x5p-1076'), -TINY)
664
self.identical(fromHex('-0x6p-1076'), -2*TINY)
665
self.identical(fromHex('-0X7p-1076'), -2*TINY)
666
self.identical(fromHex('-0X8p-1076'), -2*TINY)
667
self.identical(fromHex('-0X9p-1076'), -2*TINY)
668
self.identical(fromHex('-0Xap-1076'), -2*TINY)
669
self.identical(fromHex('-0xbp-1076'), -3*TINY)
670
self.identical(fromHex('-0xcp-1076'), -3*TINY)
671
self.identical(fromHex('-0Xdp-1076'), -3*TINY)
672
self.identical(fromHex('-0xep-1076'), -4*TINY)
673
self.identical(fromHex('-0Xfp-1076'), -4*TINY)
674
self.identical(fromHex('-0X10p-1076'), -4*TINY)
676
# ... and near MIN ...
677
self.identical(fromHex('0x0.ffffffffffffd6p-1022'), MIN-3*TINY)
678
self.identical(fromHex('0x0.ffffffffffffd8p-1022'), MIN-2*TINY)
679
self.identical(fromHex('0x0.ffffffffffffdap-1022'), MIN-2*TINY)
680
self.identical(fromHex('0x0.ffffffffffffdcp-1022'), MIN-2*TINY)
681
self.identical(fromHex('0x0.ffffffffffffdep-1022'), MIN-2*TINY)
682
self.identical(fromHex('0x0.ffffffffffffe0p-1022'), MIN-2*TINY)
683
self.identical(fromHex('0x0.ffffffffffffe2p-1022'), MIN-2*TINY)
684
self.identical(fromHex('0x0.ffffffffffffe4p-1022'), MIN-2*TINY)
685
self.identical(fromHex('0x0.ffffffffffffe6p-1022'), MIN-2*TINY)
686
self.identical(fromHex('0x0.ffffffffffffe8p-1022'), MIN-2*TINY)
687
self.identical(fromHex('0x0.ffffffffffffeap-1022'), MIN-TINY)
688
self.identical(fromHex('0x0.ffffffffffffecp-1022'), MIN-TINY)
689
self.identical(fromHex('0x0.ffffffffffffeep-1022'), MIN-TINY)
690
self.identical(fromHex('0x0.fffffffffffff0p-1022'), MIN-TINY)
691
self.identical(fromHex('0x0.fffffffffffff2p-1022'), MIN-TINY)
692
self.identical(fromHex('0x0.fffffffffffff4p-1022'), MIN-TINY)
693
self.identical(fromHex('0x0.fffffffffffff6p-1022'), MIN-TINY)
694
self.identical(fromHex('0x0.fffffffffffff8p-1022'), MIN)
695
self.identical(fromHex('0x0.fffffffffffffap-1022'), MIN)
696
self.identical(fromHex('0x0.fffffffffffffcp-1022'), MIN)
697
self.identical(fromHex('0x0.fffffffffffffep-1022'), MIN)
698
self.identical(fromHex('0x1.00000000000000p-1022'), MIN)
699
self.identical(fromHex('0x1.00000000000002p-1022'), MIN)
700
self.identical(fromHex('0x1.00000000000004p-1022'), MIN)
701
self.identical(fromHex('0x1.00000000000006p-1022'), MIN)
702
self.identical(fromHex('0x1.00000000000008p-1022'), MIN)
703
self.identical(fromHex('0x1.0000000000000ap-1022'), MIN+TINY)
704
self.identical(fromHex('0x1.0000000000000cp-1022'), MIN+TINY)
705
self.identical(fromHex('0x1.0000000000000ep-1022'), MIN+TINY)
706
self.identical(fromHex('0x1.00000000000010p-1022'), MIN+TINY)
707
self.identical(fromHex('0x1.00000000000012p-1022'), MIN+TINY)
708
self.identical(fromHex('0x1.00000000000014p-1022'), MIN+TINY)
709
self.identical(fromHex('0x1.00000000000016p-1022'), MIN+TINY)
710
self.identical(fromHex('0x1.00000000000018p-1022'), MIN+2*TINY)
713
self.identical(fromHex('0x0.fffffffffffff0p0'), 1.0-EPS)
714
self.identical(fromHex('0x0.fffffffffffff1p0'), 1.0-EPS)
715
self.identical(fromHex('0X0.fffffffffffff2p0'), 1.0-EPS)
716
self.identical(fromHex('0x0.fffffffffffff3p0'), 1.0-EPS)
717
self.identical(fromHex('0X0.fffffffffffff4p0'), 1.0-EPS)
718
self.identical(fromHex('0X0.fffffffffffff5p0'), 1.0-EPS/2)
719
self.identical(fromHex('0X0.fffffffffffff6p0'), 1.0-EPS/2)
720
self.identical(fromHex('0x0.fffffffffffff7p0'), 1.0-EPS/2)
721
self.identical(fromHex('0x0.fffffffffffff8p0'), 1.0-EPS/2)
722
self.identical(fromHex('0X0.fffffffffffff9p0'), 1.0-EPS/2)
723
self.identical(fromHex('0X0.fffffffffffffap0'), 1.0-EPS/2)
724
self.identical(fromHex('0x0.fffffffffffffbp0'), 1.0-EPS/2)
725
self.identical(fromHex('0X0.fffffffffffffcp0'), 1.0)
726
self.identical(fromHex('0x0.fffffffffffffdp0'), 1.0)
727
self.identical(fromHex('0X0.fffffffffffffep0'), 1.0)
728
self.identical(fromHex('0x0.ffffffffffffffp0'), 1.0)
729
self.identical(fromHex('0X1.00000000000000p0'), 1.0)
730
self.identical(fromHex('0X1.00000000000001p0'), 1.0)
731
self.identical(fromHex('0x1.00000000000002p0'), 1.0)
732
self.identical(fromHex('0X1.00000000000003p0'), 1.0)
733
self.identical(fromHex('0x1.00000000000004p0'), 1.0)
734
self.identical(fromHex('0X1.00000000000005p0'), 1.0)
735
self.identical(fromHex('0X1.00000000000006p0'), 1.0)
736
self.identical(fromHex('0X1.00000000000007p0'), 1.0)
737
self.identical(fromHex('0x1.00000000000007ffffffffffffffffffffp0'),
739
self.identical(fromHex('0x1.00000000000008p0'), 1.0)
740
self.identical(fromHex('0x1.00000000000008000000000000000001p0'),
742
self.identical(fromHex('0X1.00000000000009p0'), 1.0+EPS)
743
self.identical(fromHex('0x1.0000000000000ap0'), 1.0+EPS)
744
self.identical(fromHex('0x1.0000000000000bp0'), 1.0+EPS)
745
self.identical(fromHex('0X1.0000000000000cp0'), 1.0+EPS)
746
self.identical(fromHex('0x1.0000000000000dp0'), 1.0+EPS)
747
self.identical(fromHex('0x1.0000000000000ep0'), 1.0+EPS)
748
self.identical(fromHex('0X1.0000000000000fp0'), 1.0+EPS)
749
self.identical(fromHex('0x1.00000000000010p0'), 1.0+EPS)
750
self.identical(fromHex('0X1.00000000000011p0'), 1.0+EPS)
751
self.identical(fromHex('0x1.00000000000012p0'), 1.0+EPS)
752
self.identical(fromHex('0X1.00000000000013p0'), 1.0+EPS)
753
self.identical(fromHex('0X1.00000000000014p0'), 1.0+EPS)
754
self.identical(fromHex('0x1.00000000000015p0'), 1.0+EPS)
755
self.identical(fromHex('0x1.00000000000016p0'), 1.0+EPS)
756
self.identical(fromHex('0X1.00000000000017p0'), 1.0+EPS)
757
self.identical(fromHex('0x1.00000000000017ffffffffffffffffffffp0'),
759
self.identical(fromHex('0x1.00000000000018p0'), 1.0+2*EPS)
760
self.identical(fromHex('0X1.00000000000018000000000000000001p0'),
762
self.identical(fromHex('0x1.00000000000019p0'), 1.0+2*EPS)
763
self.identical(fromHex('0X1.0000000000001ap0'), 1.0+2*EPS)
764
self.identical(fromHex('0X1.0000000000001bp0'), 1.0+2*EPS)
765
self.identical(fromHex('0x1.0000000000001cp0'), 1.0+2*EPS)
766
self.identical(fromHex('0x1.0000000000001dp0'), 1.0+2*EPS)
767
self.identical(fromHex('0x1.0000000000001ep0'), 1.0+2*EPS)
768
self.identical(fromHex('0X1.0000000000001fp0'), 1.0+2*EPS)
769
self.identical(fromHex('0x1.00000000000020p0'), 1.0+2*EPS)
771
def test_roundtrip(self):
773
return fromHex(toHex(x))
775
for x in [NAN, INF, self.MAX, self.MIN, self.MIN-self.TINY, self.TINY, 0.0]:
776
self.identical(x, roundtrip(x))
777
self.identical(-x, roundtrip(-x))
779
# fromHex(toHex(x)) should exactly recover x, for any non-NaN float x.
781
for i in range(10000):
782
e = random.randrange(-1200, 1200)
784
s = random.choice([1.0, -1.0])
787
except OverflowError:
790
self.identical(x, fromHex(toHex(x)))
794
support.run_unittest(
796
FormatFunctionsTestCase,
797
UnknownFormatTestCase,
805
if __name__ == '__main__':