symbian-qemu-0.9.1-12/python-2.6.1/Lib/test/test_float.py
changeset 1 2fb8b9db1c86
equal deleted inserted replaced
0:ffa851df0825 1:2fb8b9db1c86
       
     1 
       
     2 import unittest, struct
       
     3 import os
       
     4 from test import test_support
       
     5 import math
       
     6 from math import isinf, isnan, copysign, ldexp
       
     7 import operator
       
     8 import random, fractions
       
     9 
       
    10 INF = float("inf")
       
    11 NAN = float("nan")
       
    12 
       
    13 class GeneralFloatCases(unittest.TestCase):
       
    14 
       
    15     def test_float(self):
       
    16         self.assertEqual(float(3.14), 3.14)
       
    17         self.assertEqual(float(314), 314.0)
       
    18         self.assertEqual(float(314L), 314.0)
       
    19         self.assertEqual(float("  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         if test_support.have_unicode:
       
    28             self.assertEqual(float(unicode("  3.14  ")), 3.14)
       
    29             self.assertEqual(float(unicode("  \u0663.\u0661\u0664  ",'raw-unicode-escape')), 3.14)
       
    30             # Implementation limitation in PyFloat_FromString()
       
    31             self.assertRaises(ValueError, float, unicode("1"*10000))
       
    32 
       
    33     @test_support.run_with_locale('LC_NUMERIC', 'fr_FR', 'de_DE')
       
    34     def test_float_with_comma(self):
       
    35         # set locale to something that doesn't use '.' for the decimal point
       
    36         # float must not accept the locale specific decimal point but
       
    37         # it still has to accept the normal python syntac
       
    38         import locale
       
    39         if not locale.localeconv()['decimal_point'] == ',':
       
    40             return
       
    41 
       
    42         self.assertEqual(float("  3.14  "), 3.14)
       
    43         self.assertEqual(float("+3.14  "), 3.14)
       
    44         self.assertEqual(float("-3.14  "), -3.14)
       
    45         self.assertEqual(float(".14  "), .14)
       
    46         self.assertEqual(float("3.  "), 3.0)
       
    47         self.assertEqual(float("3.e3  "), 3000.0)
       
    48         self.assertEqual(float("3.2e3  "), 3200.0)
       
    49         self.assertEqual(float("2.5e-1  "), 0.25)
       
    50         self.assertEqual(float("5e-1"), 0.5)
       
    51         self.assertRaises(ValueError, float, "  3,14  ")
       
    52         self.assertRaises(ValueError, float, "  +3,14  ")
       
    53         self.assertRaises(ValueError, float, "  -3,14  ")
       
    54         self.assertRaises(ValueError, float, "  0x3.1  ")
       
    55         self.assertRaises(ValueError, float, "  -0x3.p-1  ")
       
    56         self.assertRaises(ValueError, float, "  +0x3.p-1  ")
       
    57         self.assertEqual(float("  25.e-1  "), 2.5)
       
    58         self.assertEqual(test_support.fcmp(float("  .25e-1  "), .025), 0)
       
    59 
       
    60     def test_floatconversion(self):
       
    61         # Make sure that calls to __float__() work properly
       
    62         class Foo0:
       
    63             def __float__(self):
       
    64                 return 42.
       
    65 
       
    66         class Foo1(object):
       
    67             def __float__(self):
       
    68                 return 42.
       
    69 
       
    70         class Foo2(float):
       
    71             def __float__(self):
       
    72                 return 42.
       
    73 
       
    74         class Foo3(float):
       
    75             def __new__(cls, value=0.):
       
    76                 return float.__new__(cls, 2*value)
       
    77 
       
    78             def __float__(self):
       
    79                 return self
       
    80 
       
    81         class Foo4(float):
       
    82             def __float__(self):
       
    83                 return 42
       
    84 
       
    85         self.assertAlmostEqual(float(Foo0()), 42.)
       
    86         self.assertAlmostEqual(float(Foo1()), 42.)
       
    87         self.assertAlmostEqual(float(Foo2()), 42.)
       
    88         self.assertAlmostEqual(float(Foo3(21)), 42.)
       
    89         self.assertRaises(TypeError, float, Foo4(42))
       
    90 
       
    91     def test_floatasratio(self):
       
    92         for f, ratio in [
       
    93                 (0.875, (7, 8)),
       
    94                 (-0.875, (-7, 8)),
       
    95                 (0.0, (0, 1)),
       
    96                 (11.5, (23, 2)),
       
    97             ]:
       
    98             self.assertEqual(f.as_integer_ratio(), ratio)
       
    99 
       
   100         for i in range(10000):
       
   101             f = random.random()
       
   102             f *= 10 ** random.randint(-100, 100)
       
   103             n, d = f.as_integer_ratio()
       
   104             self.assertEqual(float(n).__truediv__(d), f)
       
   105 
       
   106         R = fractions.Fraction
       
   107         self.assertEqual(R(0, 1),
       
   108                          R(*float(0.0).as_integer_ratio()))
       
   109         self.assertEqual(R(5, 2),
       
   110                          R(*float(2.5).as_integer_ratio()))
       
   111         self.assertEqual(R(1, 2),
       
   112                          R(*float(0.5).as_integer_ratio()))
       
   113         self.assertEqual(R(4728779608739021, 2251799813685248),
       
   114                          R(*float(2.1).as_integer_ratio()))
       
   115         self.assertEqual(R(-4728779608739021, 2251799813685248),
       
   116                          R(*float(-2.1).as_integer_ratio()))
       
   117         self.assertEqual(R(-2100, 1),
       
   118                          R(*float(-2100.0).as_integer_ratio()))
       
   119 
       
   120         self.assertRaises(OverflowError, float('inf').as_integer_ratio)
       
   121         self.assertRaises(OverflowError, float('-inf').as_integer_ratio)
       
   122         self.assertRaises(ValueError, float('nan').as_integer_ratio)
       
   123 
       
   124 class FormatFunctionsTestCase(unittest.TestCase):
       
   125 
       
   126     def setUp(self):
       
   127         self.save_formats = {'double':float.__getformat__('double'),
       
   128                              'float':float.__getformat__('float')}
       
   129 
       
   130     def tearDown(self):
       
   131         float.__setformat__('double', self.save_formats['double'])
       
   132         float.__setformat__('float', self.save_formats['float'])
       
   133 
       
   134     def test_getformat(self):
       
   135         self.assert_(float.__getformat__('double') in
       
   136                      ['unknown', 'IEEE, big-endian', 'IEEE, little-endian'])
       
   137         self.assert_(float.__getformat__('float') in
       
   138                      ['unknown', 'IEEE, big-endian', 'IEEE, little-endian'])
       
   139         self.assertRaises(ValueError, float.__getformat__, 'chicken')
       
   140         self.assertRaises(TypeError, float.__getformat__, 1)
       
   141 
       
   142     def test_setformat(self):
       
   143         for t in 'double', 'float':
       
   144             float.__setformat__(t, 'unknown')
       
   145             if self.save_formats[t] == 'IEEE, big-endian':
       
   146                 self.assertRaises(ValueError, float.__setformat__,
       
   147                                   t, 'IEEE, little-endian')
       
   148             elif self.save_formats[t] == 'IEEE, little-endian':
       
   149                 self.assertRaises(ValueError, float.__setformat__,
       
   150                                   t, 'IEEE, big-endian')
       
   151             else:
       
   152                 self.assertRaises(ValueError, float.__setformat__,
       
   153                                   t, 'IEEE, big-endian')
       
   154                 self.assertRaises(ValueError, float.__setformat__,
       
   155                                   t, 'IEEE, little-endian')
       
   156             self.assertRaises(ValueError, float.__setformat__,
       
   157                               t, 'chicken')
       
   158         self.assertRaises(ValueError, float.__setformat__,
       
   159                           'chicken', 'unknown')
       
   160 
       
   161 BE_DOUBLE_INF = '\x7f\xf0\x00\x00\x00\x00\x00\x00'
       
   162 LE_DOUBLE_INF = ''.join(reversed(BE_DOUBLE_INF))
       
   163 BE_DOUBLE_NAN = '\x7f\xf8\x00\x00\x00\x00\x00\x00'
       
   164 LE_DOUBLE_NAN = ''.join(reversed(BE_DOUBLE_NAN))
       
   165 
       
   166 BE_FLOAT_INF = '\x7f\x80\x00\x00'
       
   167 LE_FLOAT_INF = ''.join(reversed(BE_FLOAT_INF))
       
   168 BE_FLOAT_NAN = '\x7f\xc0\x00\x00'
       
   169 LE_FLOAT_NAN = ''.join(reversed(BE_FLOAT_NAN))
       
   170 
       
   171 # on non-IEEE platforms, attempting to unpack a bit pattern
       
   172 # representing an infinity or a NaN should raise an exception.
       
   173 
       
   174 class UnknownFormatTestCase(unittest.TestCase):
       
   175     def setUp(self):
       
   176         self.save_formats = {'double':float.__getformat__('double'),
       
   177                              'float':float.__getformat__('float')}
       
   178         float.__setformat__('double', 'unknown')
       
   179         float.__setformat__('float', 'unknown')
       
   180 
       
   181     def tearDown(self):
       
   182         float.__setformat__('double', self.save_formats['double'])
       
   183         float.__setformat__('float', self.save_formats['float'])
       
   184 
       
   185     def test_double_specials_dont_unpack(self):
       
   186         for fmt, data in [('>d', BE_DOUBLE_INF),
       
   187                           ('>d', BE_DOUBLE_NAN),
       
   188                           ('<d', LE_DOUBLE_INF),
       
   189                           ('<d', LE_DOUBLE_NAN)]:
       
   190             self.assertRaises(ValueError, struct.unpack, fmt, data)
       
   191 
       
   192     def test_float_specials_dont_unpack(self):
       
   193         for fmt, data in [('>f', BE_FLOAT_INF),
       
   194                           ('>f', BE_FLOAT_NAN),
       
   195                           ('<f', LE_FLOAT_INF),
       
   196                           ('<f', LE_FLOAT_NAN)]:
       
   197             self.assertRaises(ValueError, struct.unpack, fmt, data)
       
   198 
       
   199 
       
   200 # on an IEEE platform, all we guarantee is that bit patterns
       
   201 # representing infinities or NaNs do not raise an exception; all else
       
   202 # is accident (today).
       
   203 # let's also try to guarantee that -0.0 and 0.0 don't get confused.
       
   204 
       
   205 class IEEEFormatTestCase(unittest.TestCase):
       
   206     if float.__getformat__("double").startswith("IEEE"):
       
   207         def test_double_specials_do_unpack(self):
       
   208             for fmt, data in [('>d', BE_DOUBLE_INF),
       
   209                               ('>d', BE_DOUBLE_NAN),
       
   210                               ('<d', LE_DOUBLE_INF),
       
   211                               ('<d', LE_DOUBLE_NAN)]:
       
   212                 struct.unpack(fmt, data)
       
   213 
       
   214     if float.__getformat__("float").startswith("IEEE"):
       
   215         def test_float_specials_do_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                 struct.unpack(fmt, data)
       
   221 
       
   222     if float.__getformat__("double").startswith("IEEE"):
       
   223         def test_negative_zero(self):
       
   224             import math
       
   225             def pos_pos():
       
   226                 return 0.0, math.atan2(0.0, -1)
       
   227             def pos_neg():
       
   228                 return 0.0, math.atan2(-0.0, -1)
       
   229             def neg_pos():
       
   230                 return -0.0, math.atan2(0.0, -1)
       
   231             def neg_neg():
       
   232                 return -0.0, math.atan2(-0.0, -1)
       
   233             self.assertEquals(pos_pos(), neg_pos())
       
   234             self.assertEquals(pos_neg(), neg_neg())
       
   235 
       
   236     if float.__getformat__("double").startswith("IEEE"):
       
   237         def test_underflow_sign(self):
       
   238             import math
       
   239             # check that -1e-1000 gives -0.0, not 0.0
       
   240             self.assertEquals(math.atan2(-1e-1000, -1), math.atan2(-0.0, -1))
       
   241             self.assertEquals(math.atan2(float('-1e-1000'), -1),
       
   242                               math.atan2(-0.0, -1))
       
   243 
       
   244 class ReprTestCase(unittest.TestCase):
       
   245     def test_repr(self):
       
   246         floats_file = open(os.path.join(os.path.split(__file__)[0],
       
   247                            'floating_points.txt'))
       
   248         for line in floats_file:
       
   249             line = line.strip()
       
   250             if not line or line.startswith('#'):
       
   251                 continue
       
   252             v = eval(line)
       
   253             self.assertEqual(v, eval(repr(v)))
       
   254         floats_file.close()
       
   255 
       
   256 # Beginning with Python 2.6 float has cross platform compatible
       
   257 # ways to create and represent inf and nan
       
   258 class InfNanTest(unittest.TestCase):
       
   259     def test_inf_from_str(self):
       
   260         self.assert_(isinf(float("inf")))
       
   261         self.assert_(isinf(float("+inf")))
       
   262         self.assert_(isinf(float("-inf")))
       
   263         self.assert_(isinf(float("infinity")))
       
   264         self.assert_(isinf(float("+infinity")))
       
   265         self.assert_(isinf(float("-infinity")))
       
   266 
       
   267         self.assertEqual(repr(float("inf")), "inf")
       
   268         self.assertEqual(repr(float("+inf")), "inf")
       
   269         self.assertEqual(repr(float("-inf")), "-inf")
       
   270         self.assertEqual(repr(float("infinity")), "inf")
       
   271         self.assertEqual(repr(float("+infinity")), "inf")
       
   272         self.assertEqual(repr(float("-infinity")), "-inf")
       
   273 
       
   274         self.assertEqual(repr(float("INF")), "inf")
       
   275         self.assertEqual(repr(float("+Inf")), "inf")
       
   276         self.assertEqual(repr(float("-iNF")), "-inf")
       
   277         self.assertEqual(repr(float("Infinity")), "inf")
       
   278         self.assertEqual(repr(float("+iNfInItY")), "inf")
       
   279         self.assertEqual(repr(float("-INFINITY")), "-inf")
       
   280 
       
   281         self.assertEqual(str(float("inf")), "inf")
       
   282         self.assertEqual(str(float("+inf")), "inf")
       
   283         self.assertEqual(str(float("-inf")), "-inf")
       
   284         self.assertEqual(str(float("infinity")), "inf")
       
   285         self.assertEqual(str(float("+infinity")), "inf")
       
   286         self.assertEqual(str(float("-infinity")), "-inf")
       
   287 
       
   288         self.assertRaises(ValueError, float, "info")
       
   289         self.assertRaises(ValueError, float, "+info")
       
   290         self.assertRaises(ValueError, float, "-info")
       
   291         self.assertRaises(ValueError, float, "in")
       
   292         self.assertRaises(ValueError, float, "+in")
       
   293         self.assertRaises(ValueError, float, "-in")
       
   294         self.assertRaises(ValueError, float, "infinit")
       
   295         self.assertRaises(ValueError, float, "+Infin")
       
   296         self.assertRaises(ValueError, float, "-INFI")
       
   297         self.assertRaises(ValueError, float, "infinitys")
       
   298 
       
   299     def test_inf_as_str(self):
       
   300         self.assertEqual(repr(1e300 * 1e300), "inf")
       
   301         self.assertEqual(repr(-1e300 * 1e300), "-inf")
       
   302 
       
   303         self.assertEqual(str(1e300 * 1e300), "inf")
       
   304         self.assertEqual(str(-1e300 * 1e300), "-inf")
       
   305 
       
   306     def test_nan_from_str(self):
       
   307         self.assert_(isnan(float("nan")))
       
   308         self.assert_(isnan(float("+nan")))
       
   309         self.assert_(isnan(float("-nan")))
       
   310 
       
   311         self.assertEqual(repr(float("nan")), "nan")
       
   312         self.assertEqual(repr(float("+nan")), "nan")
       
   313         self.assertEqual(repr(float("-nan")), "nan")
       
   314 
       
   315         self.assertEqual(repr(float("NAN")), "nan")
       
   316         self.assertEqual(repr(float("+NAn")), "nan")
       
   317         self.assertEqual(repr(float("-NaN")), "nan")
       
   318 
       
   319         self.assertEqual(str(float("nan")), "nan")
       
   320         self.assertEqual(str(float("+nan")), "nan")
       
   321         self.assertEqual(str(float("-nan")), "nan")
       
   322 
       
   323         self.assertRaises(ValueError, float, "nana")
       
   324         self.assertRaises(ValueError, float, "+nana")
       
   325         self.assertRaises(ValueError, float, "-nana")
       
   326         self.assertRaises(ValueError, float, "na")
       
   327         self.assertRaises(ValueError, float, "+na")
       
   328         self.assertRaises(ValueError, float, "-na")
       
   329 
       
   330     def test_nan_as_str(self):
       
   331         self.assertEqual(repr(1e300 * 1e300 * 0), "nan")
       
   332         self.assertEqual(repr(-1e300 * 1e300 * 0), "nan")
       
   333 
       
   334         self.assertEqual(str(1e300 * 1e300 * 0), "nan")
       
   335         self.assertEqual(str(-1e300 * 1e300 * 0), "nan")
       
   336 
       
   337     def notest_float_nan(self):
       
   338         self.assert_(NAN.is_nan())
       
   339         self.failIf(INF.is_nan())
       
   340         self.failIf((0.).is_nan())
       
   341 
       
   342     def notest_float_inf(self):
       
   343         self.assert_(INF.is_inf())
       
   344         self.failIf(NAN.is_inf())
       
   345         self.failIf((0.).is_inf())
       
   346 
       
   347 fromHex = float.fromhex
       
   348 toHex = float.hex
       
   349 class HexFloatTestCase(unittest.TestCase):
       
   350     MAX = fromHex('0x.fffffffffffff8p+1024')  # max normal
       
   351     MIN = fromHex('0x1p-1022')                # min normal
       
   352     TINY = fromHex('0x0.0000000000001p-1022') # min subnormal
       
   353     EPS = fromHex('0x0.0000000000001p0') # diff between 1.0 and next float up
       
   354 
       
   355     def identical(self, x, y):
       
   356         # check that floats x and y are identical, or that both
       
   357         # are NaNs
       
   358         if isnan(x) or isnan(y):
       
   359             if isnan(x) == isnan(y):
       
   360                 return
       
   361         elif x == y and (x != 0.0 or copysign(1.0, x) == copysign(1.0, y)):
       
   362             return
       
   363         self.fail('%r not identical to %r' % (x, y))
       
   364 
       
   365     def test_ends(self):
       
   366         self.identical(self.MIN, ldexp(1.0, -1022))
       
   367         self.identical(self.TINY, ldexp(1.0, -1074))
       
   368         self.identical(self.EPS, ldexp(1.0, -52))
       
   369         self.identical(self.MAX, 2.*(ldexp(1.0, 1023) - ldexp(1.0, 970)))
       
   370 
       
   371     def test_invalid_inputs(self):
       
   372         invalid_inputs = [
       
   373             'infi',   # misspelt infinities and nans
       
   374             '-Infinit',
       
   375             '++inf',
       
   376             '-+Inf',
       
   377             '--nan',
       
   378             '+-NaN',
       
   379             'snan',
       
   380             'NaNs',
       
   381             'nna',
       
   382             '0xnan',
       
   383             '',
       
   384             ' ',
       
   385             'x1.0p0',
       
   386             '0xX1.0p0',
       
   387             '+ 0x1.0p0', # internal whitespace
       
   388             '- 0x1.0p0',
       
   389             '0 x1.0p0',
       
   390             '0x 1.0p0',
       
   391             '0x1 2.0p0',
       
   392             '+0x1 .0p0',
       
   393             '0x1. 0p0',
       
   394             '-0x1.0 1p0',
       
   395             '-0x1.0 p0',
       
   396             '+0x1.0p +0',
       
   397             '0x1.0p -0',
       
   398             '0x1.0p 0',
       
   399             '+0x1.0p+ 0',
       
   400             '-0x1.0p- 0',
       
   401             '++0x1.0p-0', # double signs
       
   402             '--0x1.0p0',
       
   403             '+-0x1.0p+0',
       
   404             '-+0x1.0p0',
       
   405             '0x1.0p++0',
       
   406             '+0x1.0p+-0',
       
   407             '-0x1.0p-+0',
       
   408             '0x1.0p--0',
       
   409             '0x1.0.p0',
       
   410             '0x.p0', # no hex digits before or after point
       
   411             '0x1,p0', # wrong decimal point character
       
   412             '0x1pa',
       
   413             u'0x1p\uff10',  # fullwidth Unicode digits
       
   414             u'\uff10x1p0',
       
   415             u'0x\uff11p0',
       
   416             u'0x1.\uff10p0',
       
   417             '0x1p0 \n 0x2p0',
       
   418             '0x1p0\0 0x1p0',  # embedded null byte is not end of string
       
   419             ]
       
   420         for x in invalid_inputs:
       
   421             try:
       
   422                 result = fromHex(x)
       
   423             except ValueError:
       
   424                 pass
       
   425             else:
       
   426                 self.fail('Expected float.fromhex(%r) to raise ValueError; '
       
   427                           'got %r instead' % (x, result))
       
   428 
       
   429 
       
   430     def test_from_hex(self):
       
   431         MIN = self.MIN;
       
   432         MAX = self.MAX;
       
   433         TINY = self.TINY;
       
   434         EPS = self.EPS;
       
   435 
       
   436         # two spellings of infinity, with optional signs; case-insensitive
       
   437         self.identical(fromHex('inf'), INF)
       
   438         self.identical(fromHex('+Inf'), INF)
       
   439         self.identical(fromHex('-INF'), -INF)
       
   440         self.identical(fromHex('iNf'), INF)
       
   441         self.identical(fromHex('Infinity'), INF)
       
   442         self.identical(fromHex('+INFINITY'), INF)
       
   443         self.identical(fromHex('-infinity'), -INF)
       
   444         self.identical(fromHex('-iNFiNitY'), -INF)
       
   445 
       
   446         # nans with optional sign; case insensitive
       
   447         self.identical(fromHex('nan'), NAN)
       
   448         self.identical(fromHex('+NaN'), NAN)
       
   449         self.identical(fromHex('-NaN'), NAN)
       
   450         self.identical(fromHex('-nAN'), NAN)
       
   451 
       
   452         # variations in input format
       
   453         self.identical(fromHex('1'), 1.0)
       
   454         self.identical(fromHex('+1'), 1.0)
       
   455         self.identical(fromHex('1.'), 1.0)
       
   456         self.identical(fromHex('1.0'), 1.0)
       
   457         self.identical(fromHex('1.0p0'), 1.0)
       
   458         self.identical(fromHex('01'), 1.0)
       
   459         self.identical(fromHex('01.'), 1.0)
       
   460         self.identical(fromHex('0x1'), 1.0)
       
   461         self.identical(fromHex('0x1.'), 1.0)
       
   462         self.identical(fromHex('0x1.0'), 1.0)
       
   463         self.identical(fromHex('+0x1.0'), 1.0)
       
   464         self.identical(fromHex('0x1p0'), 1.0)
       
   465         self.identical(fromHex('0X1p0'), 1.0)
       
   466         self.identical(fromHex('0X1P0'), 1.0)
       
   467         self.identical(fromHex('0x1P0'), 1.0)
       
   468         self.identical(fromHex('0x1.p0'), 1.0)
       
   469         self.identical(fromHex('0x1.0p0'), 1.0)
       
   470         self.identical(fromHex('0x.1p4'), 1.0)
       
   471         self.identical(fromHex('0x.1p04'), 1.0)
       
   472         self.identical(fromHex('0x.1p004'), 1.0)
       
   473         self.identical(fromHex('0x1p+0'), 1.0)
       
   474         self.identical(fromHex('0x1P-0'), 1.0)
       
   475         self.identical(fromHex('+0x1p0'), 1.0)
       
   476         self.identical(fromHex('0x01p0'), 1.0)
       
   477         self.identical(fromHex('0x1p00'), 1.0)
       
   478         self.identical(fromHex(u'0x1p0'), 1.0)
       
   479         self.identical(fromHex(' 0x1p0 '), 1.0)
       
   480         self.identical(fromHex('\n 0x1p0'), 1.0)
       
   481         self.identical(fromHex('0x1p0 \t'), 1.0)
       
   482         self.identical(fromHex('0xap0'), 10.0)
       
   483         self.identical(fromHex('0xAp0'), 10.0)
       
   484         self.identical(fromHex('0xaP0'), 10.0)
       
   485         self.identical(fromHex('0xAP0'), 10.0)
       
   486         self.identical(fromHex('0xbep0'), 190.0)
       
   487         self.identical(fromHex('0xBep0'), 190.0)
       
   488         self.identical(fromHex('0xbEp0'), 190.0)
       
   489         self.identical(fromHex('0XBE0P-4'), 190.0)
       
   490         self.identical(fromHex('0xBEp0'), 190.0)
       
   491         self.identical(fromHex('0xB.Ep4'), 190.0)
       
   492         self.identical(fromHex('0x.BEp8'), 190.0)
       
   493         self.identical(fromHex('0x.0BEp12'), 190.0)
       
   494 
       
   495         # moving the point around
       
   496         pi = fromHex('0x1.921fb54442d18p1')
       
   497         self.identical(fromHex('0x.006487ed5110b46p11'), pi)
       
   498         self.identical(fromHex('0x.00c90fdaa22168cp10'), pi)
       
   499         self.identical(fromHex('0x.01921fb54442d18p9'), pi)
       
   500         self.identical(fromHex('0x.03243f6a8885a3p8'), pi)
       
   501         self.identical(fromHex('0x.06487ed5110b46p7'), pi)
       
   502         self.identical(fromHex('0x.0c90fdaa22168cp6'), pi)
       
   503         self.identical(fromHex('0x.1921fb54442d18p5'), pi)
       
   504         self.identical(fromHex('0x.3243f6a8885a3p4'), pi)
       
   505         self.identical(fromHex('0x.6487ed5110b46p3'), pi)
       
   506         self.identical(fromHex('0x.c90fdaa22168cp2'), pi)
       
   507         self.identical(fromHex('0x1.921fb54442d18p1'), pi)
       
   508         self.identical(fromHex('0x3.243f6a8885a3p0'), pi)
       
   509         self.identical(fromHex('0x6.487ed5110b46p-1'), pi)
       
   510         self.identical(fromHex('0xc.90fdaa22168cp-2'), pi)
       
   511         self.identical(fromHex('0x19.21fb54442d18p-3'), pi)
       
   512         self.identical(fromHex('0x32.43f6a8885a3p-4'), pi)
       
   513         self.identical(fromHex('0x64.87ed5110b46p-5'), pi)
       
   514         self.identical(fromHex('0xc9.0fdaa22168cp-6'), pi)
       
   515         self.identical(fromHex('0x192.1fb54442d18p-7'), pi)
       
   516         self.identical(fromHex('0x324.3f6a8885a3p-8'), pi)
       
   517         self.identical(fromHex('0x648.7ed5110b46p-9'), pi)
       
   518         self.identical(fromHex('0xc90.fdaa22168cp-10'), pi)
       
   519         self.identical(fromHex('0x1921.fb54442d18p-11'), pi)
       
   520         # ...
       
   521         self.identical(fromHex('0x1921fb54442d1.8p-47'), pi)
       
   522         self.identical(fromHex('0x3243f6a8885a3p-48'), pi)
       
   523         self.identical(fromHex('0x6487ed5110b46p-49'), pi)
       
   524         self.identical(fromHex('0xc90fdaa22168cp-50'), pi)
       
   525         self.identical(fromHex('0x1921fb54442d18p-51'), pi)
       
   526         self.identical(fromHex('0x3243f6a8885a30p-52'), pi)
       
   527         self.identical(fromHex('0x6487ed5110b460p-53'), pi)
       
   528         self.identical(fromHex('0xc90fdaa22168c0p-54'), pi)
       
   529         self.identical(fromHex('0x1921fb54442d180p-55'), pi)
       
   530 
       
   531 
       
   532         # results that should overflow...
       
   533         self.assertRaises(OverflowError, fromHex, '-0x1p1024')
       
   534         self.assertRaises(OverflowError, fromHex, '0x1p+1025')
       
   535         self.assertRaises(OverflowError, fromHex, '+0X1p1030')
       
   536         self.assertRaises(OverflowError, fromHex, '-0x1p+1100')
       
   537         self.assertRaises(OverflowError, fromHex, '0X1p123456789123456789')
       
   538         self.assertRaises(OverflowError, fromHex, '+0X.8p+1025')
       
   539         self.assertRaises(OverflowError, fromHex, '+0x0.8p1025')
       
   540         self.assertRaises(OverflowError, fromHex, '-0x0.4p1026')
       
   541         self.assertRaises(OverflowError, fromHex, '0X2p+1023')
       
   542         self.assertRaises(OverflowError, fromHex, '0x2.p1023')
       
   543         self.assertRaises(OverflowError, fromHex, '-0x2.0p+1023')
       
   544         self.assertRaises(OverflowError, fromHex, '+0X4p+1022')
       
   545         self.assertRaises(OverflowError, fromHex, '0x1.ffffffffffffffp+1023')
       
   546         self.assertRaises(OverflowError, fromHex, '-0X1.fffffffffffff9p1023')
       
   547         self.assertRaises(OverflowError, fromHex, '0X1.fffffffffffff8p1023')
       
   548         self.assertRaises(OverflowError, fromHex, '+0x3.fffffffffffffp1022')
       
   549         self.assertRaises(OverflowError, fromHex, '0x3fffffffffffffp+970')
       
   550         self.assertRaises(OverflowError, fromHex, '0x10000000000000000p960')
       
   551         self.assertRaises(OverflowError, fromHex, '-0Xffffffffffffffffp960')
       
   552 
       
   553         # ...and those that round to +-max float
       
   554         self.identical(fromHex('+0x1.fffffffffffffp+1023'), MAX)
       
   555         self.identical(fromHex('-0X1.fffffffffffff7p1023'), -MAX)
       
   556         self.identical(fromHex('0X1.fffffffffffff7fffffffffffffp1023'), MAX)
       
   557 
       
   558         # zeros
       
   559         self.identical(fromHex('0x0p0'), 0.0)
       
   560         self.identical(fromHex('0x0p1000'), 0.0)
       
   561         self.identical(fromHex('-0x0p1023'), -0.0)
       
   562         self.identical(fromHex('0X0p1024'), 0.0)
       
   563         self.identical(fromHex('-0x0p1025'), -0.0)
       
   564         self.identical(fromHex('0X0p2000'), 0.0)
       
   565         self.identical(fromHex('0x0p123456789123456789'), 0.0)
       
   566         self.identical(fromHex('-0X0p-0'), -0.0)
       
   567         self.identical(fromHex('-0X0p-1000'), -0.0)
       
   568         self.identical(fromHex('0x0p-1023'), 0.0)
       
   569         self.identical(fromHex('-0X0p-1024'), -0.0)
       
   570         self.identical(fromHex('-0x0p-1025'), -0.0)
       
   571         self.identical(fromHex('-0x0p-1072'), -0.0)
       
   572         self.identical(fromHex('0X0p-1073'), 0.0)
       
   573         self.identical(fromHex('-0x0p-1074'), -0.0)
       
   574         self.identical(fromHex('0x0p-1075'), 0.0)
       
   575         self.identical(fromHex('0X0p-1076'), 0.0)
       
   576         self.identical(fromHex('-0X0p-2000'), -0.0)
       
   577         self.identical(fromHex('-0x0p-123456789123456789'), -0.0)
       
   578 
       
   579         # values that should underflow to 0
       
   580         self.identical(fromHex('0X1p-1075'), 0.0)
       
   581         self.identical(fromHex('-0X1p-1075'), -0.0)
       
   582         self.identical(fromHex('-0x1p-123456789123456789'), -0.0)
       
   583         self.identical(fromHex('0x1.00000000000000001p-1075'), TINY)
       
   584         self.identical(fromHex('-0x1.1p-1075'), -TINY)
       
   585         self.identical(fromHex('0x1.fffffffffffffffffp-1075'), TINY)
       
   586 
       
   587         # check round-half-even is working correctly near 0 ...
       
   588         self.identical(fromHex('0x1p-1076'), 0.0)
       
   589         self.identical(fromHex('0X2p-1076'), 0.0)
       
   590         self.identical(fromHex('0X3p-1076'), TINY)
       
   591         self.identical(fromHex('0x4p-1076'), TINY)
       
   592         self.identical(fromHex('0X5p-1076'), TINY)
       
   593         self.identical(fromHex('0X6p-1076'), 2*TINY)
       
   594         self.identical(fromHex('0x7p-1076'), 2*TINY)
       
   595         self.identical(fromHex('0X8p-1076'), 2*TINY)
       
   596         self.identical(fromHex('0X9p-1076'), 2*TINY)
       
   597         self.identical(fromHex('0xap-1076'), 2*TINY)
       
   598         self.identical(fromHex('0Xbp-1076'), 3*TINY)
       
   599         self.identical(fromHex('0xcp-1076'), 3*TINY)
       
   600         self.identical(fromHex('0Xdp-1076'), 3*TINY)
       
   601         self.identical(fromHex('0Xep-1076'), 4*TINY)
       
   602         self.identical(fromHex('0xfp-1076'), 4*TINY)
       
   603         self.identical(fromHex('0x10p-1076'), 4*TINY)
       
   604         self.identical(fromHex('-0x1p-1076'), -0.0)
       
   605         self.identical(fromHex('-0X2p-1076'), -0.0)
       
   606         self.identical(fromHex('-0x3p-1076'), -TINY)
       
   607         self.identical(fromHex('-0X4p-1076'), -TINY)
       
   608         self.identical(fromHex('-0x5p-1076'), -TINY)
       
   609         self.identical(fromHex('-0x6p-1076'), -2*TINY)
       
   610         self.identical(fromHex('-0X7p-1076'), -2*TINY)
       
   611         self.identical(fromHex('-0X8p-1076'), -2*TINY)
       
   612         self.identical(fromHex('-0X9p-1076'), -2*TINY)
       
   613         self.identical(fromHex('-0Xap-1076'), -2*TINY)
       
   614         self.identical(fromHex('-0xbp-1076'), -3*TINY)
       
   615         self.identical(fromHex('-0xcp-1076'), -3*TINY)
       
   616         self.identical(fromHex('-0Xdp-1076'), -3*TINY)
       
   617         self.identical(fromHex('-0xep-1076'), -4*TINY)
       
   618         self.identical(fromHex('-0Xfp-1076'), -4*TINY)
       
   619         self.identical(fromHex('-0X10p-1076'), -4*TINY)
       
   620 
       
   621         # ... and near MIN ...
       
   622         self.identical(fromHex('0x0.ffffffffffffd6p-1022'), MIN-3*TINY)
       
   623         self.identical(fromHex('0x0.ffffffffffffd8p-1022'), MIN-2*TINY)
       
   624         self.identical(fromHex('0x0.ffffffffffffdap-1022'), MIN-2*TINY)
       
   625         self.identical(fromHex('0x0.ffffffffffffdcp-1022'), MIN-2*TINY)
       
   626         self.identical(fromHex('0x0.ffffffffffffdep-1022'), MIN-2*TINY)
       
   627         self.identical(fromHex('0x0.ffffffffffffe0p-1022'), MIN-2*TINY)
       
   628         self.identical(fromHex('0x0.ffffffffffffe2p-1022'), MIN-2*TINY)
       
   629         self.identical(fromHex('0x0.ffffffffffffe4p-1022'), MIN-2*TINY)
       
   630         self.identical(fromHex('0x0.ffffffffffffe6p-1022'), MIN-2*TINY)
       
   631         self.identical(fromHex('0x0.ffffffffffffe8p-1022'), MIN-2*TINY)
       
   632         self.identical(fromHex('0x0.ffffffffffffeap-1022'), MIN-TINY)
       
   633         self.identical(fromHex('0x0.ffffffffffffecp-1022'), MIN-TINY)
       
   634         self.identical(fromHex('0x0.ffffffffffffeep-1022'), MIN-TINY)
       
   635         self.identical(fromHex('0x0.fffffffffffff0p-1022'), MIN-TINY)
       
   636         self.identical(fromHex('0x0.fffffffffffff2p-1022'), MIN-TINY)
       
   637         self.identical(fromHex('0x0.fffffffffffff4p-1022'), MIN-TINY)
       
   638         self.identical(fromHex('0x0.fffffffffffff6p-1022'), MIN-TINY)
       
   639         self.identical(fromHex('0x0.fffffffffffff8p-1022'), MIN)
       
   640         self.identical(fromHex('0x0.fffffffffffffap-1022'), MIN)
       
   641         self.identical(fromHex('0x0.fffffffffffffcp-1022'), MIN)
       
   642         self.identical(fromHex('0x0.fffffffffffffep-1022'), MIN)
       
   643         self.identical(fromHex('0x1.00000000000000p-1022'), MIN)
       
   644         self.identical(fromHex('0x1.00000000000002p-1022'), MIN)
       
   645         self.identical(fromHex('0x1.00000000000004p-1022'), MIN)
       
   646         self.identical(fromHex('0x1.00000000000006p-1022'), MIN)
       
   647         self.identical(fromHex('0x1.00000000000008p-1022'), MIN)
       
   648         self.identical(fromHex('0x1.0000000000000ap-1022'), MIN+TINY)
       
   649         self.identical(fromHex('0x1.0000000000000cp-1022'), MIN+TINY)
       
   650         self.identical(fromHex('0x1.0000000000000ep-1022'), MIN+TINY)
       
   651         self.identical(fromHex('0x1.00000000000010p-1022'), MIN+TINY)
       
   652         self.identical(fromHex('0x1.00000000000012p-1022'), MIN+TINY)
       
   653         self.identical(fromHex('0x1.00000000000014p-1022'), MIN+TINY)
       
   654         self.identical(fromHex('0x1.00000000000016p-1022'), MIN+TINY)
       
   655         self.identical(fromHex('0x1.00000000000018p-1022'), MIN+2*TINY)
       
   656 
       
   657         # ... and near 1.0.
       
   658         self.identical(fromHex('0x0.fffffffffffff0p0'), 1.0-EPS)
       
   659         self.identical(fromHex('0x0.fffffffffffff1p0'), 1.0-EPS)
       
   660         self.identical(fromHex('0X0.fffffffffffff2p0'), 1.0-EPS)
       
   661         self.identical(fromHex('0x0.fffffffffffff3p0'), 1.0-EPS)
       
   662         self.identical(fromHex('0X0.fffffffffffff4p0'), 1.0-EPS)
       
   663         self.identical(fromHex('0X0.fffffffffffff5p0'), 1.0-EPS/2)
       
   664         self.identical(fromHex('0X0.fffffffffffff6p0'), 1.0-EPS/2)
       
   665         self.identical(fromHex('0x0.fffffffffffff7p0'), 1.0-EPS/2)
       
   666         self.identical(fromHex('0x0.fffffffffffff8p0'), 1.0-EPS/2)
       
   667         self.identical(fromHex('0X0.fffffffffffff9p0'), 1.0-EPS/2)
       
   668         self.identical(fromHex('0X0.fffffffffffffap0'), 1.0-EPS/2)
       
   669         self.identical(fromHex('0x0.fffffffffffffbp0'), 1.0-EPS/2)
       
   670         self.identical(fromHex('0X0.fffffffffffffcp0'), 1.0)
       
   671         self.identical(fromHex('0x0.fffffffffffffdp0'), 1.0)
       
   672         self.identical(fromHex('0X0.fffffffffffffep0'), 1.0)
       
   673         self.identical(fromHex('0x0.ffffffffffffffp0'), 1.0)
       
   674         self.identical(fromHex('0X1.00000000000000p0'), 1.0)
       
   675         self.identical(fromHex('0X1.00000000000001p0'), 1.0)
       
   676         self.identical(fromHex('0x1.00000000000002p0'), 1.0)
       
   677         self.identical(fromHex('0X1.00000000000003p0'), 1.0)
       
   678         self.identical(fromHex('0x1.00000000000004p0'), 1.0)
       
   679         self.identical(fromHex('0X1.00000000000005p0'), 1.0)
       
   680         self.identical(fromHex('0X1.00000000000006p0'), 1.0)
       
   681         self.identical(fromHex('0X1.00000000000007p0'), 1.0)
       
   682         self.identical(fromHex('0x1.00000000000007ffffffffffffffffffffp0'),
       
   683                        1.0)
       
   684         self.identical(fromHex('0x1.00000000000008p0'), 1.0)
       
   685         self.identical(fromHex('0x1.00000000000008000000000000000001p0'),
       
   686                        1+EPS)
       
   687         self.identical(fromHex('0X1.00000000000009p0'), 1.0+EPS)
       
   688         self.identical(fromHex('0x1.0000000000000ap0'), 1.0+EPS)
       
   689         self.identical(fromHex('0x1.0000000000000bp0'), 1.0+EPS)
       
   690         self.identical(fromHex('0X1.0000000000000cp0'), 1.0+EPS)
       
   691         self.identical(fromHex('0x1.0000000000000dp0'), 1.0+EPS)
       
   692         self.identical(fromHex('0x1.0000000000000ep0'), 1.0+EPS)
       
   693         self.identical(fromHex('0X1.0000000000000fp0'), 1.0+EPS)
       
   694         self.identical(fromHex('0x1.00000000000010p0'), 1.0+EPS)
       
   695         self.identical(fromHex('0X1.00000000000011p0'), 1.0+EPS)
       
   696         self.identical(fromHex('0x1.00000000000012p0'), 1.0+EPS)
       
   697         self.identical(fromHex('0X1.00000000000013p0'), 1.0+EPS)
       
   698         self.identical(fromHex('0X1.00000000000014p0'), 1.0+EPS)
       
   699         self.identical(fromHex('0x1.00000000000015p0'), 1.0+EPS)
       
   700         self.identical(fromHex('0x1.00000000000016p0'), 1.0+EPS)
       
   701         self.identical(fromHex('0X1.00000000000017p0'), 1.0+EPS)
       
   702         self.identical(fromHex('0x1.00000000000017ffffffffffffffffffffp0'),
       
   703                        1.0+EPS)
       
   704         self.identical(fromHex('0x1.00000000000018p0'), 1.0+2*EPS)
       
   705         self.identical(fromHex('0X1.00000000000018000000000000000001p0'),
       
   706                        1.0+2*EPS)
       
   707         self.identical(fromHex('0x1.00000000000019p0'), 1.0+2*EPS)
       
   708         self.identical(fromHex('0X1.0000000000001ap0'), 1.0+2*EPS)
       
   709         self.identical(fromHex('0X1.0000000000001bp0'), 1.0+2*EPS)
       
   710         self.identical(fromHex('0x1.0000000000001cp0'), 1.0+2*EPS)
       
   711         self.identical(fromHex('0x1.0000000000001dp0'), 1.0+2*EPS)
       
   712         self.identical(fromHex('0x1.0000000000001ep0'), 1.0+2*EPS)
       
   713         self.identical(fromHex('0X1.0000000000001fp0'), 1.0+2*EPS)
       
   714         self.identical(fromHex('0x1.00000000000020p0'), 1.0+2*EPS)
       
   715 
       
   716     def test_roundtrip(self):
       
   717         def roundtrip(x):
       
   718             return fromHex(toHex(x))
       
   719 
       
   720         for x in [NAN, INF, self.MAX, self.MIN, self.MIN-self.TINY, self.TINY, 0.0]:
       
   721             self.identical(x, roundtrip(x))
       
   722             self.identical(-x, roundtrip(-x))
       
   723 
       
   724         # fromHex(toHex(x)) should exactly recover x, for any non-NaN float x.
       
   725         import random
       
   726         for i in xrange(10000):
       
   727             e = random.randrange(-1200, 1200)
       
   728             m = random.random()
       
   729             s = random.choice([1.0, -1.0])
       
   730             try:
       
   731                 x = s*ldexp(m, e)
       
   732             except OverflowError:
       
   733                 pass
       
   734             else:
       
   735                 self.identical(x, fromHex(toHex(x)))
       
   736 
       
   737 
       
   738 def test_main():
       
   739     test_support.run_unittest(
       
   740         GeneralFloatCases,
       
   741         FormatFunctionsTestCase,
       
   742         UnknownFormatTestCase,
       
   743         IEEEFormatTestCase,
       
   744         ReprTestCase,
       
   745         InfNanTest,
       
   746         HexFloatTestCase,
       
   747         )
       
   748 
       
   749 if __name__ == '__main__':
       
   750     test_main()