blob: ff9cfeee53e89dde70156c85625db95ab298294c [file] [log] [blame]
Michael W. Hudsonba283e22005-05-27 15:23:20 +00001
2import unittest, struct
Christian Heimes284d9272007-12-10 22:28:56 +00003import os
Michael W. Hudsonba283e22005-05-27 15:23:20 +00004from test import test_support
Christian Heimes6f341092008-04-18 23:13:07 +00005import math
Mark Dickinson7103aa42008-07-15 19:08:33 +00006from math import isinf, isnan, copysign, ldexp
Christian Heimes6f341092008-04-18 23:13:07 +00007import operator
Mark Dickinsonbd15a062009-11-18 19:33:35 +00008import random
9import fractions
10import sys
Michael W. Hudsonba283e22005-05-27 15:23:20 +000011
Christian Heimes6f341092008-04-18 23:13:07 +000012INF = float("inf")
13NAN = float("nan")
Christian Heimes0a8143f2007-12-18 23:22:54 +000014
Mark Dickinson99d652e2009-12-30 12:12:23 +000015# decorator for skipping tests on non-IEEE 754 platforms
16requires_IEEE_754 = unittest.skipUnless(
17 float.__getformat__("double").startswith("IEEE"),
18 "test requires IEEE 754 doubles")
19
Mark Dickinson61a0d052009-04-29 21:57:15 +000020#locate file with float format test values
21test_dir = os.path.dirname(__file__) or os.curdir
22format_testfile = os.path.join(test_dir, 'formatfloat_testcases.txt')
23
Benjamin Peterson979395b2008-05-03 21:35:18 +000024class GeneralFloatCases(unittest.TestCase):
25
26 def test_float(self):
27 self.assertEqual(float(3.14), 3.14)
28 self.assertEqual(float(314), 314.0)
29 self.assertEqual(float(314L), 314.0)
30 self.assertEqual(float(" 3.14 "), 3.14)
31 self.assertRaises(ValueError, float, " 0x3.1 ")
32 self.assertRaises(ValueError, float, " -0x3.p-1 ")
33 self.assertRaises(ValueError, float, " +0x3.p-1 ")
34 self.assertRaises(ValueError, float, "++3.14")
35 self.assertRaises(ValueError, float, "+-3.14")
36 self.assertRaises(ValueError, float, "-+3.14")
37 self.assertRaises(ValueError, float, "--3.14")
Amaury Forgeot d'Arcfeb8cad2008-09-06 20:53:51 +000038 if test_support.have_unicode:
Benjamin Peterson979395b2008-05-03 21:35:18 +000039 self.assertEqual(float(unicode(" 3.14 ")), 3.14)
40 self.assertEqual(float(unicode(" \u0663.\u0661\u0664 ",'raw-unicode-escape')), 3.14)
Benjamin Peterson979395b2008-05-03 21:35:18 +000041
Mark Dickinson53e9fa42009-10-27 22:09:33 +000042 # extra long strings should no longer be a problem
43 # (in 2.6, long unicode inputs to float raised ValueError)
44 float('.' + '1'*1000)
45 float(unicode('.' + '1'*1000))
46
Benjamin Peterson979395b2008-05-03 21:35:18 +000047 @test_support.run_with_locale('LC_NUMERIC', 'fr_FR', 'de_DE')
48 def test_float_with_comma(self):
49 # set locale to something that doesn't use '.' for the decimal point
50 # float must not accept the locale specific decimal point but
51 # it still has to accept the normal python syntac
52 import locale
53 if not locale.localeconv()['decimal_point'] == ',':
54 return
55
56 self.assertEqual(float(" 3.14 "), 3.14)
57 self.assertEqual(float("+3.14 "), 3.14)
58 self.assertEqual(float("-3.14 "), -3.14)
59 self.assertEqual(float(".14 "), .14)
60 self.assertEqual(float("3. "), 3.0)
61 self.assertEqual(float("3.e3 "), 3000.0)
62 self.assertEqual(float("3.2e3 "), 3200.0)
63 self.assertEqual(float("2.5e-1 "), 0.25)
64 self.assertEqual(float("5e-1"), 0.5)
65 self.assertRaises(ValueError, float, " 3,14 ")
66 self.assertRaises(ValueError, float, " +3,14 ")
67 self.assertRaises(ValueError, float, " -3,14 ")
68 self.assertRaises(ValueError, float, " 0x3.1 ")
69 self.assertRaises(ValueError, float, " -0x3.p-1 ")
70 self.assertRaises(ValueError, float, " +0x3.p-1 ")
71 self.assertEqual(float(" 25.e-1 "), 2.5)
Benjamin Petersona853a892008-09-06 23:19:15 +000072 self.assertEqual(test_support.fcmp(float(" .25e-1 "), .025), 0)
Benjamin Peterson979395b2008-05-03 21:35:18 +000073
74 def test_floatconversion(self):
75 # Make sure that calls to __float__() work properly
76 class Foo0:
77 def __float__(self):
78 return 42.
79
80 class Foo1(object):
81 def __float__(self):
82 return 42.
83
84 class Foo2(float):
85 def __float__(self):
86 return 42.
87
88 class Foo3(float):
89 def __new__(cls, value=0.):
90 return float.__new__(cls, 2*value)
91
92 def __float__(self):
93 return self
94
95 class Foo4(float):
96 def __float__(self):
97 return 42
98
Benjamin Peterson99d36f12009-04-15 21:26:36 +000099 # Issue 5759: __float__ not called on str subclasses (though it is on
100 # unicode subclasses).
101 class FooStr(str):
102 def __float__(self):
103 return float(str(self)) + 1
104
105 class FooUnicode(unicode):
106 def __float__(self):
107 return float(unicode(self)) + 1
108
Benjamin Peterson979395b2008-05-03 21:35:18 +0000109 self.assertAlmostEqual(float(Foo0()), 42.)
110 self.assertAlmostEqual(float(Foo1()), 42.)
111 self.assertAlmostEqual(float(Foo2()), 42.)
112 self.assertAlmostEqual(float(Foo3(21)), 42.)
113 self.assertRaises(TypeError, float, Foo4(42))
Benjamin Peterson99d36f12009-04-15 21:26:36 +0000114 self.assertAlmostEqual(float(FooUnicode('8')), 9.)
115 self.assertAlmostEqual(float(FooStr('8')), 9.)
Benjamin Peterson979395b2008-05-03 21:35:18 +0000116
117 def test_floatasratio(self):
118 for f, ratio in [
119 (0.875, (7, 8)),
120 (-0.875, (-7, 8)),
121 (0.0, (0, 1)),
122 (11.5, (23, 2)),
123 ]:
124 self.assertEqual(f.as_integer_ratio(), ratio)
125
126 for i in range(10000):
127 f = random.random()
128 f *= 10 ** random.randint(-100, 100)
129 n, d = f.as_integer_ratio()
130 self.assertEqual(float(n).__truediv__(d), f)
131
132 R = fractions.Fraction
133 self.assertEqual(R(0, 1),
134 R(*float(0.0).as_integer_ratio()))
135 self.assertEqual(R(5, 2),
136 R(*float(2.5).as_integer_ratio()))
137 self.assertEqual(R(1, 2),
138 R(*float(0.5).as_integer_ratio()))
139 self.assertEqual(R(4728779608739021, 2251799813685248),
140 R(*float(2.1).as_integer_ratio()))
141 self.assertEqual(R(-4728779608739021, 2251799813685248),
142 R(*float(-2.1).as_integer_ratio()))
143 self.assertEqual(R(-2100, 1),
144 R(*float(-2100.0).as_integer_ratio()))
145
146 self.assertRaises(OverflowError, float('inf').as_integer_ratio)
147 self.assertRaises(OverflowError, float('-inf').as_integer_ratio)
148 self.assertRaises(ValueError, float('nan').as_integer_ratio)
149
Mark Dickinson99d652e2009-12-30 12:12:23 +0000150 def assertEqualAndEqualSign(self, a, b):
151 # fail unless a == b and a and b have the same sign bit;
152 # the only difference from assertEqual is that this test
153 # distingishes -0.0 and 0.0.
154 self.assertEqual((a, copysign(1.0, a)), (b, copysign(1.0, b)))
155
156 @requires_IEEE_754
157 def test_float_pow(self):
158 # test builtin pow and ** operator for IEEE 754 special cases.
159 # Special cases taken from section F.9.4.4 of the C99 specification
160
161 for pow_op in pow, operator.pow:
162 # x**NAN is NAN for any x except 1
163 self.assertTrue(isnan(pow_op(-INF, NAN)))
164 self.assertTrue(isnan(pow_op(-2.0, NAN)))
165 self.assertTrue(isnan(pow_op(-1.0, NAN)))
166 self.assertTrue(isnan(pow_op(-0.5, NAN)))
167 self.assertTrue(isnan(pow_op(-0.0, NAN)))
168 self.assertTrue(isnan(pow_op(0.0, NAN)))
169 self.assertTrue(isnan(pow_op(0.5, NAN)))
170 self.assertTrue(isnan(pow_op(2.0, NAN)))
171 self.assertTrue(isnan(pow_op(INF, NAN)))
172 self.assertTrue(isnan(pow_op(NAN, NAN)))
173
174 # NAN**y is NAN for any y except +-0
175 self.assertTrue(isnan(pow_op(NAN, -INF)))
176 self.assertTrue(isnan(pow_op(NAN, -2.0)))
177 self.assertTrue(isnan(pow_op(NAN, -1.0)))
178 self.assertTrue(isnan(pow_op(NAN, -0.5)))
179 self.assertTrue(isnan(pow_op(NAN, 0.5)))
180 self.assertTrue(isnan(pow_op(NAN, 1.0)))
181 self.assertTrue(isnan(pow_op(NAN, 2.0)))
182 self.assertTrue(isnan(pow_op(NAN, INF)))
183
184 # (+-0)**y raises ZeroDivisionError for y a negative odd integer
185 self.assertRaises(ZeroDivisionError, pow_op, -0.0, -1.0)
186 self.assertRaises(ZeroDivisionError, pow_op, 0.0, -1.0)
187
188 # (+-0)**y raises ZeroDivisionError for y finite and negative
189 # but not an odd integer
190 self.assertRaises(ZeroDivisionError, pow_op, -0.0, -2.0)
191 self.assertRaises(ZeroDivisionError, pow_op, -0.0, -0.5)
192 self.assertRaises(ZeroDivisionError, pow_op, 0.0, -2.0)
193 self.assertRaises(ZeroDivisionError, pow_op, 0.0, -0.5)
194
195 # (+-0)**y is +-0 for y a positive odd integer
196 self.assertEqualAndEqualSign(pow_op(-0.0, 1.0), -0.0)
197 self.assertEqualAndEqualSign(pow_op(0.0, 1.0), 0.0)
198
199 # (+-0)**y is 0 for y finite and positive but not an odd integer
200 self.assertEqualAndEqualSign(pow_op(-0.0, 0.5), 0.0)
201 self.assertEqualAndEqualSign(pow_op(-0.0, 2.0), 0.0)
202 self.assertEqualAndEqualSign(pow_op(0.0, 0.5), 0.0)
203 self.assertEqualAndEqualSign(pow_op(0.0, 2.0), 0.0)
204
205 # (-1)**+-inf is 1
206 self.assertEqualAndEqualSign(pow_op(-1.0, -INF), 1.0)
207 self.assertEqualAndEqualSign(pow_op(-1.0, INF), 1.0)
208
209 # 1**y is 1 for any y, even if y is an infinity or nan
210 self.assertEqualAndEqualSign(pow_op(1.0, -INF), 1.0)
211 self.assertEqualAndEqualSign(pow_op(1.0, -2.0), 1.0)
212 self.assertEqualAndEqualSign(pow_op(1.0, -1.0), 1.0)
213 self.assertEqualAndEqualSign(pow_op(1.0, -0.5), 1.0)
214 self.assertEqualAndEqualSign(pow_op(1.0, -0.0), 1.0)
215 self.assertEqualAndEqualSign(pow_op(1.0, 0.0), 1.0)
216 self.assertEqualAndEqualSign(pow_op(1.0, 0.5), 1.0)
217 self.assertEqualAndEqualSign(pow_op(1.0, 1.0), 1.0)
218 self.assertEqualAndEqualSign(pow_op(1.0, 2.0), 1.0)
219 self.assertEqualAndEqualSign(pow_op(1.0, INF), 1.0)
220 self.assertEqualAndEqualSign(pow_op(1.0, NAN), 1.0)
221
222 # x**+-0 is 1 for any x, even if x is a zero, infinity, or nan
223 self.assertEqualAndEqualSign(pow_op(-INF, 0.0), 1.0)
224 self.assertEqualAndEqualSign(pow_op(-2.0, 0.0), 1.0)
225 self.assertEqualAndEqualSign(pow_op(-1.0, 0.0), 1.0)
226 self.assertEqualAndEqualSign(pow_op(-0.5, 0.0), 1.0)
227 self.assertEqualAndEqualSign(pow_op(-0.0, 0.0), 1.0)
228 self.assertEqualAndEqualSign(pow_op(0.0, 0.0), 1.0)
229 self.assertEqualAndEqualSign(pow_op(0.5, 0.0), 1.0)
230 self.assertEqualAndEqualSign(pow_op(1.0, 0.0), 1.0)
231 self.assertEqualAndEqualSign(pow_op(2.0, 0.0), 1.0)
232 self.assertEqualAndEqualSign(pow_op(INF, 0.0), 1.0)
233 self.assertEqualAndEqualSign(pow_op(NAN, 0.0), 1.0)
234 self.assertEqualAndEqualSign(pow_op(-INF, -0.0), 1.0)
235 self.assertEqualAndEqualSign(pow_op(-2.0, -0.0), 1.0)
236 self.assertEqualAndEqualSign(pow_op(-1.0, -0.0), 1.0)
237 self.assertEqualAndEqualSign(pow_op(-0.5, -0.0), 1.0)
238 self.assertEqualAndEqualSign(pow_op(-0.0, -0.0), 1.0)
239 self.assertEqualAndEqualSign(pow_op(0.0, -0.0), 1.0)
240 self.assertEqualAndEqualSign(pow_op(0.5, -0.0), 1.0)
241 self.assertEqualAndEqualSign(pow_op(1.0, -0.0), 1.0)
242 self.assertEqualAndEqualSign(pow_op(2.0, -0.0), 1.0)
243 self.assertEqualAndEqualSign(pow_op(INF, -0.0), 1.0)
244 self.assertEqualAndEqualSign(pow_op(NAN, -0.0), 1.0)
245
246 # x**y raises ValueError for finite negative x and non-integral y
247 self.assertRaises(ValueError, pow_op, -2.0, -0.5)
248 self.assertRaises(ValueError, pow_op, -2.0, 0.5)
249 self.assertRaises(ValueError, pow_op, -1.0, -0.5)
250 self.assertRaises(ValueError, pow_op, -1.0, 0.5)
251 self.assertRaises(ValueError, pow_op, -0.5, -0.5)
252 self.assertRaises(ValueError, pow_op, -0.5, 0.5)
253
254 # x**-INF is INF for abs(x) < 1
255 self.assertEqualAndEqualSign(pow_op(-0.5, -INF), INF)
256 self.assertEqualAndEqualSign(pow_op(-0.0, -INF), INF)
257 self.assertEqualAndEqualSign(pow_op(0.0, -INF), INF)
258 self.assertEqualAndEqualSign(pow_op(0.5, -INF), INF)
259
260 # x**-INF is 0 for abs(x) > 1
261 self.assertEqualAndEqualSign(pow_op(-INF, -INF), 0.0)
262 self.assertEqualAndEqualSign(pow_op(-2.0, -INF), 0.0)
263 self.assertEqualAndEqualSign(pow_op(2.0, -INF), 0.0)
264 self.assertEqualAndEqualSign(pow_op(INF, -INF), 0.0)
265
266 # x**INF is 0 for abs(x) < 1
267 self.assertEqualAndEqualSign(pow_op(-0.5, INF), 0.0)
268 self.assertEqualAndEqualSign(pow_op(-0.0, INF), 0.0)
269 self.assertEqualAndEqualSign(pow_op(0.0, INF), 0.0)
270 self.assertEqualAndEqualSign(pow_op(0.5, INF), 0.0)
271
272 # x**INF is INF for abs(x) > 1
273 self.assertEqualAndEqualSign(pow_op(-INF, INF), INF)
274 self.assertEqualAndEqualSign(pow_op(-2.0, INF), INF)
275 self.assertEqualAndEqualSign(pow_op(2.0, INF), INF)
276 self.assertEqualAndEqualSign(pow_op(INF, INF), INF)
277
278 # (-INF)**y is -0.0 for y a negative odd integer
279 self.assertEqualAndEqualSign(pow_op(-INF, -1.0), -0.0)
280
281 # (-INF)**y is 0.0 for y negative but not an odd integer
282 self.assertEqualAndEqualSign(pow_op(-INF, -0.5), 0.0)
283 self.assertEqualAndEqualSign(pow_op(-INF, -2.0), 0.0)
284
285 # (-INF)**y is -INF for y a positive odd integer
286 self.assertEqualAndEqualSign(pow_op(-INF, 1.0), -INF)
287
288 # (-INF)**y is INF for y positive but not an odd integer
289 self.assertEqualAndEqualSign(pow_op(-INF, 0.5), INF)
290 self.assertEqualAndEqualSign(pow_op(-INF, 2.0), INF)
291
292 # INF**y is INF for y positive
293 self.assertEqualAndEqualSign(pow_op(INF, 0.5), INF)
294 self.assertEqualAndEqualSign(pow_op(INF, 1.0), INF)
295 self.assertEqualAndEqualSign(pow_op(INF, 2.0), INF)
296
297 # INF**y is 0.0 for y negative
298 self.assertEqualAndEqualSign(pow_op(INF, -2.0), 0.0)
299 self.assertEqualAndEqualSign(pow_op(INF, -1.0), 0.0)
300 self.assertEqualAndEqualSign(pow_op(INF, -0.5), 0.0)
301
302 # basic checks not covered by the special cases above
303 self.assertEqualAndEqualSign(pow_op(-2.0, -2.0), 0.25)
304 self.assertEqualAndEqualSign(pow_op(-2.0, -1.0), -0.5)
305 self.assertEqualAndEqualSign(pow_op(-2.0, -0.0), 1.0)
306 self.assertEqualAndEqualSign(pow_op(-2.0, 0.0), 1.0)
307 self.assertEqualAndEqualSign(pow_op(-2.0, 1.0), -2.0)
308 self.assertEqualAndEqualSign(pow_op(-2.0, 2.0), 4.0)
309 self.assertEqualAndEqualSign(pow_op(-1.0, -2.0), 1.0)
310 self.assertEqualAndEqualSign(pow_op(-1.0, -1.0), -1.0)
311 self.assertEqualAndEqualSign(pow_op(-1.0, -0.0), 1.0)
312 self.assertEqualAndEqualSign(pow_op(-1.0, 0.0), 1.0)
313 self.assertEqualAndEqualSign(pow_op(-1.0, 1.0), -1.0)
314 self.assertEqualAndEqualSign(pow_op(-1.0, 2.0), 1.0)
315 self.assertEqualAndEqualSign(pow_op(2.0, -2.0), 0.25)
316 self.assertEqualAndEqualSign(pow_op(2.0, -1.0), 0.5)
317 self.assertEqualAndEqualSign(pow_op(2.0, -0.0), 1.0)
318 self.assertEqualAndEqualSign(pow_op(2.0, 0.0), 1.0)
319 self.assertEqualAndEqualSign(pow_op(2.0, 1.0), 2.0)
320 self.assertEqualAndEqualSign(pow_op(2.0, 2.0), 4.0)
321
322 # 1 ** large and -1 ** large; some libms apparently
323 # have problems with these
324 self.assertEqualAndEqualSign(pow_op(1.0, -1e100), 1.0)
325 self.assertEqualAndEqualSign(pow_op(1.0, 1e100), 1.0)
326 self.assertEqualAndEqualSign(pow_op(-1.0, -1e100), 1.0)
327 self.assertEqualAndEqualSign(pow_op(-1.0, 1e100), 1.0)
328
329 # check sign for results that underflow to 0
330 self.assertEqualAndEqualSign(pow_op(-2.0, -2000.0), 0.0)
331 self.assertRaises(ValueError, pow_op, -2.0, -2000.5)
332 self.assertEqualAndEqualSign(pow_op(-2.0, -2001.0), -0.0)
333 self.assertEqualAndEqualSign(pow_op(2.0, -2000.0), 0.0)
334 self.assertEqualAndEqualSign(pow_op(2.0, -2000.5), 0.0)
335 self.assertEqualAndEqualSign(pow_op(2.0, -2001.0), 0.0)
336 self.assertEqualAndEqualSign(pow_op(-0.5, 2000.0), 0.0)
337 self.assertRaises(ValueError, pow_op, -0.5, 2000.5)
338 self.assertEqualAndEqualSign(pow_op(-0.5, 2001.0), -0.0)
339 self.assertEqualAndEqualSign(pow_op(0.5, 2000.0), 0.0)
340 self.assertEqualAndEqualSign(pow_op(0.5, 2000.5), 0.0)
341 self.assertEqualAndEqualSign(pow_op(0.5, 2001.0), 0.0)
342
343 # check we don't raise an exception for subnormal results,
344 # and validate signs. Tests currently disabled, since
345 # they fail on systems where a subnormal result from pow
346 # is flushed to zero (e.g. Debian/ia64.)
347 #self.assertTrue(0.0 < pow_op(0.5, 1048) < 1e-315)
348 #self.assertTrue(0.0 < pow_op(-0.5, 1048) < 1e-315)
349 #self.assertTrue(0.0 < pow_op(0.5, 1047) < 1e-315)
350 #self.assertTrue(0.0 > pow_op(-0.5, 1047) > -1e-315)
351 #self.assertTrue(0.0 < pow_op(2.0, -1048) < 1e-315)
352 #self.assertTrue(0.0 < pow_op(-2.0, -1048) < 1e-315)
353 #self.assertTrue(0.0 < pow_op(2.0, -1047) < 1e-315)
354 #self.assertTrue(0.0 > pow_op(-2.0, -1047) > -1e-315)
355
356
Michael W. Hudsonba283e22005-05-27 15:23:20 +0000357class FormatFunctionsTestCase(unittest.TestCase):
358
359 def setUp(self):
360 self.save_formats = {'double':float.__getformat__('double'),
361 'float':float.__getformat__('float')}
362
363 def tearDown(self):
364 float.__setformat__('double', self.save_formats['double'])
365 float.__setformat__('float', self.save_formats['float'])
366
367 def test_getformat(self):
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000368 self.assertTrue(float.__getformat__('double') in
Michael W. Hudsonba283e22005-05-27 15:23:20 +0000369 ['unknown', 'IEEE, big-endian', 'IEEE, little-endian'])
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000370 self.assertTrue(float.__getformat__('float') in
Michael W. Hudsonba283e22005-05-27 15:23:20 +0000371 ['unknown', 'IEEE, big-endian', 'IEEE, little-endian'])
372 self.assertRaises(ValueError, float.__getformat__, 'chicken')
373 self.assertRaises(TypeError, float.__getformat__, 1)
374
375 def test_setformat(self):
376 for t in 'double', 'float':
377 float.__setformat__(t, 'unknown')
378 if self.save_formats[t] == 'IEEE, big-endian':
379 self.assertRaises(ValueError, float.__setformat__,
380 t, 'IEEE, little-endian')
381 elif self.save_formats[t] == 'IEEE, little-endian':
382 self.assertRaises(ValueError, float.__setformat__,
383 t, 'IEEE, big-endian')
384 else:
385 self.assertRaises(ValueError, float.__setformat__,
386 t, 'IEEE, big-endian')
387 self.assertRaises(ValueError, float.__setformat__,
388 t, 'IEEE, little-endian')
389 self.assertRaises(ValueError, float.__setformat__,
390 t, 'chicken')
391 self.assertRaises(ValueError, float.__setformat__,
392 'chicken', 'unknown')
393
394BE_DOUBLE_INF = '\x7f\xf0\x00\x00\x00\x00\x00\x00'
395LE_DOUBLE_INF = ''.join(reversed(BE_DOUBLE_INF))
396BE_DOUBLE_NAN = '\x7f\xf8\x00\x00\x00\x00\x00\x00'
397LE_DOUBLE_NAN = ''.join(reversed(BE_DOUBLE_NAN))
398
399BE_FLOAT_INF = '\x7f\x80\x00\x00'
400LE_FLOAT_INF = ''.join(reversed(BE_FLOAT_INF))
401BE_FLOAT_NAN = '\x7f\xc0\x00\x00'
402LE_FLOAT_NAN = ''.join(reversed(BE_FLOAT_NAN))
403
404# on non-IEEE platforms, attempting to unpack a bit pattern
405# representing an infinity or a NaN should raise an exception.
406
407class UnknownFormatTestCase(unittest.TestCase):
408 def setUp(self):
409 self.save_formats = {'double':float.__getformat__('double'),
410 'float':float.__getformat__('float')}
411 float.__setformat__('double', 'unknown')
412 float.__setformat__('float', 'unknown')
Tim Peters5d36a552005-06-03 22:40:27 +0000413
Michael W. Hudsonba283e22005-05-27 15:23:20 +0000414 def tearDown(self):
415 float.__setformat__('double', self.save_formats['double'])
416 float.__setformat__('float', self.save_formats['float'])
417
418 def test_double_specials_dont_unpack(self):
419 for fmt, data in [('>d', BE_DOUBLE_INF),
420 ('>d', BE_DOUBLE_NAN),
421 ('<d', LE_DOUBLE_INF),
422 ('<d', LE_DOUBLE_NAN)]:
423 self.assertRaises(ValueError, struct.unpack, fmt, data)
424
425 def test_float_specials_dont_unpack(self):
426 for fmt, data in [('>f', BE_FLOAT_INF),
427 ('>f', BE_FLOAT_NAN),
428 ('<f', LE_FLOAT_INF),
429 ('<f', LE_FLOAT_NAN)]:
430 self.assertRaises(ValueError, struct.unpack, fmt, data)
431
432
433# on an IEEE platform, all we guarantee is that bit patterns
434# representing infinities or NaNs do not raise an exception; all else
435# is accident (today).
Alex Martellid8672aa2007-08-22 21:14:17 +0000436# let's also try to guarantee that -0.0 and 0.0 don't get confused.
Michael W. Hudsonba283e22005-05-27 15:23:20 +0000437
438class IEEEFormatTestCase(unittest.TestCase):
439 if float.__getformat__("double").startswith("IEEE"):
440 def test_double_specials_do_unpack(self):
441 for fmt, data in [('>d', BE_DOUBLE_INF),
442 ('>d', BE_DOUBLE_NAN),
443 ('<d', LE_DOUBLE_INF),
444 ('<d', LE_DOUBLE_NAN)]:
445 struct.unpack(fmt, data)
446
447 if float.__getformat__("float").startswith("IEEE"):
448 def test_float_specials_do_unpack(self):
449 for fmt, data in [('>f', BE_FLOAT_INF),
450 ('>f', BE_FLOAT_NAN),
451 ('<f', LE_FLOAT_INF),
452 ('<f', LE_FLOAT_NAN)]:
453 struct.unpack(fmt, data)
454
Alex Martellid8672aa2007-08-22 21:14:17 +0000455 if float.__getformat__("double").startswith("IEEE"):
456 def test_negative_zero(self):
457 import math
458 def pos_pos():
459 return 0.0, math.atan2(0.0, -1)
460 def pos_neg():
461 return 0.0, math.atan2(-0.0, -1)
462 def neg_pos():
463 return -0.0, math.atan2(0.0, -1)
464 def neg_neg():
465 return -0.0, math.atan2(-0.0, -1)
466 self.assertEquals(pos_pos(), neg_pos())
467 self.assertEquals(pos_neg(), neg_neg())
468
Guido van Rossum3b835492008-01-05 00:59:59 +0000469 if float.__getformat__("double").startswith("IEEE"):
470 def test_underflow_sign(self):
471 import math
472 # check that -1e-1000 gives -0.0, not 0.0
473 self.assertEquals(math.atan2(-1e-1000, -1), math.atan2(-0.0, -1))
474 self.assertEquals(math.atan2(float('-1e-1000'), -1),
475 math.atan2(-0.0, -1))
Michael W. Hudsonba283e22005-05-27 15:23:20 +0000476
Eric Smitha985a3a2009-05-05 18:26:08 +0000477 def test_format(self):
478 # these should be rewritten to use both format(x, spec) and
479 # x.__format__(spec)
480
481 self.assertEqual(format(0.0, 'f'), '0.000000')
482
483 # the default is 'g', except for empty format spec
484 self.assertEqual(format(0.0, ''), '0.0')
485 self.assertEqual(format(0.01, ''), '0.01')
486 self.assertEqual(format(0.01, 'g'), '0.01')
487
488 # empty presentation type should format in the same way as str
489 # (issue 5920)
490 x = 100/7.
491 self.assertEqual(format(x, ''), str(x))
492 self.assertEqual(format(x, '-'), str(x))
493 self.assertEqual(format(x, '>'), str(x))
494 self.assertEqual(format(x, '2'), str(x))
495
496 self.assertEqual(format(1.0, 'f'), '1.000000')
497
498 self.assertEqual(format(-1.0, 'f'), '-1.000000')
499
500 self.assertEqual(format( 1.0, ' f'), ' 1.000000')
501 self.assertEqual(format(-1.0, ' f'), '-1.000000')
502 self.assertEqual(format( 1.0, '+f'), '+1.000000')
503 self.assertEqual(format(-1.0, '+f'), '-1.000000')
504
505 # % formatting
506 self.assertEqual(format(-1.0, '%'), '-100.000000%')
507
508 # conversion to string should fail
509 self.assertRaises(ValueError, format, 3.0, "s")
510
511 # other format specifiers shouldn't work on floats,
512 # in particular int specifiers
513 for format_spec in ([chr(x) for x in range(ord('a'), ord('z')+1)] +
514 [chr(x) for x in range(ord('A'), ord('Z')+1)]):
515 if not format_spec in 'eEfFgGn%':
516 self.assertRaises(ValueError, format, 0.0, format_spec)
517 self.assertRaises(ValueError, format, 1.0, format_spec)
518 self.assertRaises(ValueError, format, -1.0, format_spec)
519 self.assertRaises(ValueError, format, 1e100, format_spec)
520 self.assertRaises(ValueError, format, -1e100, format_spec)
521 self.assertRaises(ValueError, format, 1e-100, format_spec)
522 self.assertRaises(ValueError, format, -1e-100, format_spec)
523
Eric Smithc4ab8332009-11-29 17:40:57 +0000524 # issue 3382: 'f' and 'F' with inf's and nan's
525 self.assertEqual('{0:f}'.format(INF), 'inf')
526 self.assertEqual('{0:F}'.format(INF), 'INF')
527 self.assertEqual('{0:f}'.format(-INF), '-inf')
528 self.assertEqual('{0:F}'.format(-INF), '-INF')
529 self.assertEqual('{0:f}'.format(NAN), 'nan')
530 self.assertEqual('{0:F}'.format(NAN), 'NAN')
531
Mark Dickinson61a0d052009-04-29 21:57:15 +0000532 @unittest.skipUnless(float.__getformat__("double").startswith("IEEE"),
533 "test requires IEEE 754 doubles")
534 def test_format_testfile(self):
535 for line in open(format_testfile):
536 if line.startswith('--'):
537 continue
538 line = line.strip()
539 if not line:
540 continue
541
542 lhs, rhs = map(str.strip, line.split('->'))
543 fmt, arg = lhs.split()
Eric Smithc4ab8332009-11-29 17:40:57 +0000544 arg = float(arg)
545 self.assertEqual(fmt % arg, rhs)
546 if not math.isnan(arg) and copysign(1.0, arg) > 0.0:
547 self.assertEqual(fmt % -arg, '-' + rhs)
Mark Dickinson61a0d052009-04-29 21:57:15 +0000548
Mark Dickinson92fcc9c2009-04-29 20:41:00 +0000549 def test_issue5864(self):
550 self.assertEquals(format(123.456, '.4'), '123.5')
551 self.assertEquals(format(1234.56, '.4'), '1.235e+03')
552 self.assertEquals(format(12345.6, '.4'), '1.235e+04')
553
Christian Heimes284d9272007-12-10 22:28:56 +0000554class ReprTestCase(unittest.TestCase):
555 def test_repr(self):
556 floats_file = open(os.path.join(os.path.split(__file__)[0],
557 'floating_points.txt'))
558 for line in floats_file:
559 line = line.strip()
560 if not line or line.startswith('#'):
561 continue
562 v = eval(line)
563 self.assertEqual(v, eval(repr(v)))
564 floats_file.close()
565
Mark Dickinson3194d142010-01-08 16:53:56 +0000566 @unittest.skipUnless(getattr(sys, 'float_repr_style', '') == 'short',
567 "applies only when using short float repr style")
568 def test_short_repr(self):
569 # test short float repr introduced in Python 3.1. One aspect
570 # of this repr is that we get some degree of str -> float ->
571 # str roundtripping. In particular, for any numeric string
572 # containing 15 or fewer significant digits, those exact same
573 # digits (modulo trailing zeros) should appear in the output.
574 # No more repr(0.03) -> "0.029999999999999999"!
575
576 test_strings = [
577 # output always includes *either* a decimal point and at
578 # least one digit after that point, or an exponent.
579 '0.0',
580 '1.0',
581 '0.01',
582 '0.02',
583 '0.03',
584 '0.04',
585 '0.05',
586 '1.23456789',
587 '10.0',
588 '100.0',
589 # values >= 1e16 get an exponent...
590 '1000000000000000.0',
591 '9999999999999990.0',
592 '1e+16',
593 '1e+17',
594 # ... and so do values < 1e-4
595 '0.001',
596 '0.001001',
597 '0.00010000000000001',
598 '0.0001',
599 '9.999999999999e-05',
600 '1e-05',
601 # values designed to provoke failure if the FPU rounding
602 # precision isn't set correctly
603 '8.72293771110361e+25',
604 '7.47005307342313e+26',
605 '2.86438000439698e+28',
606 '8.89142905246179e+28',
607 '3.08578087079232e+35',
608 ]
609
610 for s in test_strings:
611 negs = '-'+s
612 self.assertEqual(s, repr(float(s)))
613 self.assertEqual(negs, repr(float(negs)))
614
Mark Dickinsonbd15a062009-11-18 19:33:35 +0000615@unittest.skipUnless(float.__getformat__("double").startswith("IEEE"),
616 "test requires IEEE 754 doubles")
617class RoundTestCase(unittest.TestCase):
618 def test_second_argument_type(self):
619 # any type with an __index__ method should be permitted as
620 # a second argument
621 self.assertAlmostEqual(round(12.34, True), 12.3)
622
623 class MyIndex(object):
624 def __index__(self): return 4
625 self.assertAlmostEqual(round(-0.123456, MyIndex()), -0.1235)
626 # but floats should be illegal
627 self.assertRaises(TypeError, round, 3.14159, 2.0)
628
629 def test_inf_nan(self):
630 # rounding an infinity or nan returns the same number;
631 # (in py3k, rounding an infinity or nan raises an error,
632 # since the result can't be represented as a long).
633 self.assertEqual(round(INF), INF)
634 self.assertEqual(round(-INF), -INF)
635 self.assertTrue(math.isnan(round(NAN)))
636 for n in range(-5, 5):
637 self.assertEqual(round(INF, n), INF)
638 self.assertEqual(round(-INF, n), -INF)
639 self.assertTrue(math.isnan(round(NAN, n)))
640
Mark Dickinsonbce78372009-11-24 10:54:58 +0000641 self.assertRaises(TypeError, round, INF, 0.0)
642 self.assertRaises(TypeError, round, -INF, 1.0)
643 self.assertRaises(TypeError, round, NAN, "ceci n'est pas un integer")
644 self.assertRaises(TypeError, round, -0.0, 1j)
645
Mark Dickinsonbd15a062009-11-18 19:33:35 +0000646 def test_large_n(self):
647 for n in [324, 325, 400, 2**31-1, 2**31, 2**32, 2**100]:
648 self.assertEqual(round(123.456, n), 123.456)
649 self.assertEqual(round(-123.456, n), -123.456)
650 self.assertEqual(round(1e300, n), 1e300)
651 self.assertEqual(round(1e-320, n), 1e-320)
652 self.assertEqual(round(1e150, 300), 1e150)
653 self.assertEqual(round(1e300, 307), 1e300)
654 self.assertEqual(round(-3.1415, 308), -3.1415)
655 self.assertEqual(round(1e150, 309), 1e150)
656 self.assertEqual(round(1.4e-315, 315), 1e-315)
657
658 def test_small_n(self):
659 for n in [-308, -309, -400, 1-2**31, -2**31, -2**31-1, -2**100]:
660 self.assertEqual(round(123.456, n), 0.0)
661 self.assertEqual(round(-123.456, n), -0.0)
662 self.assertEqual(round(1e300, n), 0.0)
663 self.assertEqual(round(1e-320, n), 0.0)
664
665 def test_overflow(self):
666 self.assertRaises(OverflowError, round, 1.6e308, -308)
667 self.assertRaises(OverflowError, round, -1.7e308, -308)
668
669 @unittest.skipUnless(getattr(sys, 'float_repr_style', '') == 'short',
670 "test applies only when using short float repr style")
671 def test_previous_round_bugs(self):
672 # particular cases that have occurred in bug reports
673 self.assertEqual(round(562949953421312.5, 1),
674 562949953421312.5)
675 self.assertEqual(round(56294995342131.5, 3),
676 56294995342131.5)
677
678 @unittest.skipUnless(getattr(sys, 'float_repr_style', '') == 'short',
679 "test applies only when using short float repr style")
680 def test_halfway_cases(self):
681 # Halfway cases need special attention, since the current
682 # implementation has to deal with them specially. Note that
683 # 2.x rounds halfway values up (i.e., away from zero) while
684 # 3.x does round-half-to-even.
685 self.assertAlmostEqual(round(0.125, 2), 0.13)
686 self.assertAlmostEqual(round(0.375, 2), 0.38)
687 self.assertAlmostEqual(round(0.625, 2), 0.63)
688 self.assertAlmostEqual(round(0.875, 2), 0.88)
689 self.assertAlmostEqual(round(-0.125, 2), -0.13)
690 self.assertAlmostEqual(round(-0.375, 2), -0.38)
691 self.assertAlmostEqual(round(-0.625, 2), -0.63)
692 self.assertAlmostEqual(round(-0.875, 2), -0.88)
693
694 self.assertAlmostEqual(round(0.25, 1), 0.3)
695 self.assertAlmostEqual(round(0.75, 1), 0.8)
696 self.assertAlmostEqual(round(-0.25, 1), -0.3)
697 self.assertAlmostEqual(round(-0.75, 1), -0.8)
698
699 self.assertEqual(round(-6.5, 0), -7.0)
700 self.assertEqual(round(-5.5, 0), -6.0)
701 self.assertEqual(round(-1.5, 0), -2.0)
702 self.assertEqual(round(-0.5, 0), -1.0)
703 self.assertEqual(round(0.5, 0), 1.0)
704 self.assertEqual(round(1.5, 0), 2.0)
705 self.assertEqual(round(2.5, 0), 3.0)
706 self.assertEqual(round(3.5, 0), 4.0)
707 self.assertEqual(round(4.5, 0), 5.0)
708 self.assertEqual(round(5.5, 0), 6.0)
709 self.assertEqual(round(6.5, 0), 7.0)
710
711 # same but without an explicit second argument; in 3.x these
712 # will give integers
713 self.assertEqual(round(-6.5), -7.0)
714 self.assertEqual(round(-5.5), -6.0)
715 self.assertEqual(round(-1.5), -2.0)
716 self.assertEqual(round(-0.5), -1.0)
717 self.assertEqual(round(0.5), 1.0)
718 self.assertEqual(round(1.5), 2.0)
719 self.assertEqual(round(2.5), 3.0)
720 self.assertEqual(round(3.5), 4.0)
721 self.assertEqual(round(4.5), 5.0)
722 self.assertEqual(round(5.5), 6.0)
723 self.assertEqual(round(6.5), 7.0)
724
725 self.assertEqual(round(-25.0, -1), -30.0)
726 self.assertEqual(round(-15.0, -1), -20.0)
727 self.assertEqual(round(-5.0, -1), -10.0)
728 self.assertEqual(round(5.0, -1), 10.0)
729 self.assertEqual(round(15.0, -1), 20.0)
730 self.assertEqual(round(25.0, -1), 30.0)
731 self.assertEqual(round(35.0, -1), 40.0)
732 self.assertEqual(round(45.0, -1), 50.0)
733 self.assertEqual(round(55.0, -1), 60.0)
734 self.assertEqual(round(65.0, -1), 70.0)
735 self.assertEqual(round(75.0, -1), 80.0)
736 self.assertEqual(round(85.0, -1), 90.0)
737 self.assertEqual(round(95.0, -1), 100.0)
738 self.assertEqual(round(12325.0, -1), 12330.0)
739
740 self.assertEqual(round(350.0, -2), 400.0)
741 self.assertEqual(round(450.0, -2), 500.0)
742
743 self.assertAlmostEqual(round(0.5e21, -21), 1e21)
744 self.assertAlmostEqual(round(1.5e21, -21), 2e21)
745 self.assertAlmostEqual(round(2.5e21, -21), 3e21)
746 self.assertAlmostEqual(round(5.5e21, -21), 6e21)
747 self.assertAlmostEqual(round(8.5e21, -21), 9e21)
748
749 self.assertAlmostEqual(round(-1.5e22, -22), -2e22)
750 self.assertAlmostEqual(round(-0.5e22, -22), -1e22)
751 self.assertAlmostEqual(round(0.5e22, -22), 1e22)
752 self.assertAlmostEqual(round(1.5e22, -22), 2e22)
753
Eric Smithf2bf0d22009-12-02 17:43:06 +0000754 @unittest.skipUnless(float.__getformat__("double").startswith("IEEE"),
755 "test requires IEEE 754 doubles")
756 def test_format_specials(self):
757 # Test formatting of nans and infs.
758
759 def test(fmt, value, expected):
760 # Test with both % and format().
761 self.assertEqual(fmt % value, expected, fmt)
762 if not '#' in fmt:
763 # Until issue 7094 is implemented, format() for floats doesn't
764 # support '#' formatting
765 fmt = fmt[1:] # strip off the %
766 self.assertEqual(format(value, fmt), expected, fmt)
767
768 for fmt in ['%e', '%f', '%g', '%.0e', '%.6f', '%.20g',
769 '%#e', '%#f', '%#g', '%#.20e', '%#.15f', '%#.3g']:
770 pfmt = '%+' + fmt[1:]
771 sfmt = '% ' + fmt[1:]
772 test(fmt, INF, 'inf')
773 test(fmt, -INF, '-inf')
774 test(fmt, NAN, 'nan')
775 test(fmt, -NAN, 'nan')
776 # When asking for a sign, it's always provided. nans are
777 # always positive.
778 test(pfmt, INF, '+inf')
779 test(pfmt, -INF, '-inf')
780 test(pfmt, NAN, '+nan')
781 test(pfmt, -NAN, '+nan')
782 # When using ' ' for a sign code, only infs can be negative.
783 # Others have a space.
784 test(sfmt, INF, ' inf')
785 test(sfmt, -INF, '-inf')
786 test(sfmt, NAN, ' nan')
787 test(sfmt, -NAN, ' nan')
788
Mark Dickinsonbd15a062009-11-18 19:33:35 +0000789
Christian Heimes0a8143f2007-12-18 23:22:54 +0000790# Beginning with Python 2.6 float has cross platform compatible
Mark Dickinsonbf9f4d82008-07-05 11:33:52 +0000791# ways to create and represent inf and nan
Christian Heimes0a8143f2007-12-18 23:22:54 +0000792class InfNanTest(unittest.TestCase):
793 def test_inf_from_str(self):
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000794 self.assertTrue(isinf(float("inf")))
795 self.assertTrue(isinf(float("+inf")))
796 self.assertTrue(isinf(float("-inf")))
797 self.assertTrue(isinf(float("infinity")))
798 self.assertTrue(isinf(float("+infinity")))
799 self.assertTrue(isinf(float("-infinity")))
Christian Heimes0a8143f2007-12-18 23:22:54 +0000800
801 self.assertEqual(repr(float("inf")), "inf")
802 self.assertEqual(repr(float("+inf")), "inf")
803 self.assertEqual(repr(float("-inf")), "-inf")
Mark Dickinsonbf9f4d82008-07-05 11:33:52 +0000804 self.assertEqual(repr(float("infinity")), "inf")
805 self.assertEqual(repr(float("+infinity")), "inf")
806 self.assertEqual(repr(float("-infinity")), "-inf")
Christian Heimes0a8143f2007-12-18 23:22:54 +0000807
808 self.assertEqual(repr(float("INF")), "inf")
809 self.assertEqual(repr(float("+Inf")), "inf")
810 self.assertEqual(repr(float("-iNF")), "-inf")
Mark Dickinsonbf9f4d82008-07-05 11:33:52 +0000811 self.assertEqual(repr(float("Infinity")), "inf")
812 self.assertEqual(repr(float("+iNfInItY")), "inf")
813 self.assertEqual(repr(float("-INFINITY")), "-inf")
Christian Heimes0a8143f2007-12-18 23:22:54 +0000814
815 self.assertEqual(str(float("inf")), "inf")
816 self.assertEqual(str(float("+inf")), "inf")
817 self.assertEqual(str(float("-inf")), "-inf")
Mark Dickinsonbf9f4d82008-07-05 11:33:52 +0000818 self.assertEqual(str(float("infinity")), "inf")
819 self.assertEqual(str(float("+infinity")), "inf")
820 self.assertEqual(str(float("-infinity")), "-inf")
Christian Heimes0a8143f2007-12-18 23:22:54 +0000821
822 self.assertRaises(ValueError, float, "info")
823 self.assertRaises(ValueError, float, "+info")
824 self.assertRaises(ValueError, float, "-info")
825 self.assertRaises(ValueError, float, "in")
826 self.assertRaises(ValueError, float, "+in")
827 self.assertRaises(ValueError, float, "-in")
Mark Dickinsonbf9f4d82008-07-05 11:33:52 +0000828 self.assertRaises(ValueError, float, "infinit")
829 self.assertRaises(ValueError, float, "+Infin")
830 self.assertRaises(ValueError, float, "-INFI")
831 self.assertRaises(ValueError, float, "infinitys")
Christian Heimes0a8143f2007-12-18 23:22:54 +0000832
833 def test_inf_as_str(self):
834 self.assertEqual(repr(1e300 * 1e300), "inf")
835 self.assertEqual(repr(-1e300 * 1e300), "-inf")
836
837 self.assertEqual(str(1e300 * 1e300), "inf")
838 self.assertEqual(str(-1e300 * 1e300), "-inf")
839
840 def test_nan_from_str(self):
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000841 self.assertTrue(isnan(float("nan")))
842 self.assertTrue(isnan(float("+nan")))
843 self.assertTrue(isnan(float("-nan")))
Christian Heimes0a8143f2007-12-18 23:22:54 +0000844
845 self.assertEqual(repr(float("nan")), "nan")
846 self.assertEqual(repr(float("+nan")), "nan")
847 self.assertEqual(repr(float("-nan")), "nan")
848
849 self.assertEqual(repr(float("NAN")), "nan")
850 self.assertEqual(repr(float("+NAn")), "nan")
851 self.assertEqual(repr(float("-NaN")), "nan")
852
853 self.assertEqual(str(float("nan")), "nan")
854 self.assertEqual(str(float("+nan")), "nan")
855 self.assertEqual(str(float("-nan")), "nan")
856
857 self.assertRaises(ValueError, float, "nana")
858 self.assertRaises(ValueError, float, "+nana")
859 self.assertRaises(ValueError, float, "-nana")
860 self.assertRaises(ValueError, float, "na")
861 self.assertRaises(ValueError, float, "+na")
862 self.assertRaises(ValueError, float, "-na")
863
864 def test_nan_as_str(self):
865 self.assertEqual(repr(1e300 * 1e300 * 0), "nan")
866 self.assertEqual(repr(-1e300 * 1e300 * 0), "nan")
867
868 self.assertEqual(str(1e300 * 1e300 * 0), "nan")
869 self.assertEqual(str(-1e300 * 1e300 * 0), "nan")
Christian Heimes284d9272007-12-10 22:28:56 +0000870
Christian Heimes6f341092008-04-18 23:13:07 +0000871 def notest_float_nan(self):
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000872 self.assertTrue(NAN.is_nan())
873 self.assertFalse(INF.is_nan())
874 self.assertFalse((0.).is_nan())
Christian Heimes6f341092008-04-18 23:13:07 +0000875
876 def notest_float_inf(self):
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000877 self.assertTrue(INF.is_inf())
878 self.assertFalse(NAN.is_inf())
879 self.assertFalse((0.).is_inf())
Christian Heimes6f341092008-04-18 23:13:07 +0000880
Mark Dickinson7103aa42008-07-15 19:08:33 +0000881fromHex = float.fromhex
882toHex = float.hex
883class HexFloatTestCase(unittest.TestCase):
884 MAX = fromHex('0x.fffffffffffff8p+1024') # max normal
885 MIN = fromHex('0x1p-1022') # min normal
886 TINY = fromHex('0x0.0000000000001p-1022') # min subnormal
887 EPS = fromHex('0x0.0000000000001p0') # diff between 1.0 and next float up
888
889 def identical(self, x, y):
890 # check that floats x and y are identical, or that both
891 # are NaNs
892 if isnan(x) or isnan(y):
893 if isnan(x) == isnan(y):
894 return
895 elif x == y and (x != 0.0 or copysign(1.0, x) == copysign(1.0, y)):
896 return
897 self.fail('%r not identical to %r' % (x, y))
898
899 def test_ends(self):
Mark Dickinson62764562008-07-15 21:55:23 +0000900 self.identical(self.MIN, ldexp(1.0, -1022))
901 self.identical(self.TINY, ldexp(1.0, -1074))
902 self.identical(self.EPS, ldexp(1.0, -52))
903 self.identical(self.MAX, 2.*(ldexp(1.0, 1023) - ldexp(1.0, 970)))
Mark Dickinson7103aa42008-07-15 19:08:33 +0000904
905 def test_invalid_inputs(self):
906 invalid_inputs = [
907 'infi', # misspelt infinities and nans
908 '-Infinit',
909 '++inf',
910 '-+Inf',
911 '--nan',
912 '+-NaN',
913 'snan',
914 'NaNs',
915 'nna',
Mark Dickinsonb1d45852009-05-11 15:33:08 +0000916 'an',
917 'nf',
918 'nfinity',
919 'inity',
920 'iinity',
Mark Dickinson7103aa42008-07-15 19:08:33 +0000921 '0xnan',
922 '',
923 ' ',
924 'x1.0p0',
925 '0xX1.0p0',
926 '+ 0x1.0p0', # internal whitespace
927 '- 0x1.0p0',
928 '0 x1.0p0',
929 '0x 1.0p0',
930 '0x1 2.0p0',
931 '+0x1 .0p0',
932 '0x1. 0p0',
933 '-0x1.0 1p0',
934 '-0x1.0 p0',
935 '+0x1.0p +0',
936 '0x1.0p -0',
937 '0x1.0p 0',
938 '+0x1.0p+ 0',
939 '-0x1.0p- 0',
940 '++0x1.0p-0', # double signs
941 '--0x1.0p0',
942 '+-0x1.0p+0',
943 '-+0x1.0p0',
944 '0x1.0p++0',
945 '+0x1.0p+-0',
946 '-0x1.0p-+0',
947 '0x1.0p--0',
948 '0x1.0.p0',
949 '0x.p0', # no hex digits before or after point
950 '0x1,p0', # wrong decimal point character
951 '0x1pa',
952 u'0x1p\uff10', # fullwidth Unicode digits
953 u'\uff10x1p0',
954 u'0x\uff11p0',
955 u'0x1.\uff10p0',
956 '0x1p0 \n 0x2p0',
957 '0x1p0\0 0x1p0', # embedded null byte is not end of string
958 ]
959 for x in invalid_inputs:
Mark Dickinson892429b2008-08-21 20:02:24 +0000960 try:
961 result = fromHex(x)
962 except ValueError:
963 pass
964 else:
965 self.fail('Expected float.fromhex(%r) to raise ValueError; '
966 'got %r instead' % (x, result))
Mark Dickinson7103aa42008-07-15 19:08:33 +0000967
968
Mark Dickinsonb1d45852009-05-11 15:33:08 +0000969 def test_whitespace(self):
970 value_pairs = [
971 ('inf', INF),
972 ('-Infinity', -INF),
973 ('nan', NAN),
974 ('1.0', 1.0),
975 ('-0x.2', -0.125),
976 ('-0.0', -0.0)
977 ]
978 whitespace = [
979 '',
980 ' ',
981 '\t',
982 '\n',
983 '\n \t',
984 '\f',
985 '\v',
986 '\r'
987 ]
988 for inp, expected in value_pairs:
989 for lead in whitespace:
990 for trail in whitespace:
991 got = fromHex(lead + inp + trail)
992 self.identical(got, expected)
993
994
Mark Dickinson7103aa42008-07-15 19:08:33 +0000995 def test_from_hex(self):
996 MIN = self.MIN;
997 MAX = self.MAX;
998 TINY = self.TINY;
999 EPS = self.EPS;
1000
1001 # two spellings of infinity, with optional signs; case-insensitive
1002 self.identical(fromHex('inf'), INF)
1003 self.identical(fromHex('+Inf'), INF)
1004 self.identical(fromHex('-INF'), -INF)
1005 self.identical(fromHex('iNf'), INF)
1006 self.identical(fromHex('Infinity'), INF)
1007 self.identical(fromHex('+INFINITY'), INF)
1008 self.identical(fromHex('-infinity'), -INF)
1009 self.identical(fromHex('-iNFiNitY'), -INF)
1010
1011 # nans with optional sign; case insensitive
1012 self.identical(fromHex('nan'), NAN)
1013 self.identical(fromHex('+NaN'), NAN)
1014 self.identical(fromHex('-NaN'), NAN)
1015 self.identical(fromHex('-nAN'), NAN)
1016
1017 # variations in input format
1018 self.identical(fromHex('1'), 1.0)
1019 self.identical(fromHex('+1'), 1.0)
1020 self.identical(fromHex('1.'), 1.0)
1021 self.identical(fromHex('1.0'), 1.0)
1022 self.identical(fromHex('1.0p0'), 1.0)
1023 self.identical(fromHex('01'), 1.0)
1024 self.identical(fromHex('01.'), 1.0)
1025 self.identical(fromHex('0x1'), 1.0)
1026 self.identical(fromHex('0x1.'), 1.0)
1027 self.identical(fromHex('0x1.0'), 1.0)
1028 self.identical(fromHex('+0x1.0'), 1.0)
1029 self.identical(fromHex('0x1p0'), 1.0)
1030 self.identical(fromHex('0X1p0'), 1.0)
1031 self.identical(fromHex('0X1P0'), 1.0)
1032 self.identical(fromHex('0x1P0'), 1.0)
1033 self.identical(fromHex('0x1.p0'), 1.0)
1034 self.identical(fromHex('0x1.0p0'), 1.0)
1035 self.identical(fromHex('0x.1p4'), 1.0)
1036 self.identical(fromHex('0x.1p04'), 1.0)
1037 self.identical(fromHex('0x.1p004'), 1.0)
1038 self.identical(fromHex('0x1p+0'), 1.0)
1039 self.identical(fromHex('0x1P-0'), 1.0)
1040 self.identical(fromHex('+0x1p0'), 1.0)
1041 self.identical(fromHex('0x01p0'), 1.0)
1042 self.identical(fromHex('0x1p00'), 1.0)
1043 self.identical(fromHex(u'0x1p0'), 1.0)
1044 self.identical(fromHex(' 0x1p0 '), 1.0)
1045 self.identical(fromHex('\n 0x1p0'), 1.0)
1046 self.identical(fromHex('0x1p0 \t'), 1.0)
1047 self.identical(fromHex('0xap0'), 10.0)
1048 self.identical(fromHex('0xAp0'), 10.0)
1049 self.identical(fromHex('0xaP0'), 10.0)
1050 self.identical(fromHex('0xAP0'), 10.0)
1051 self.identical(fromHex('0xbep0'), 190.0)
1052 self.identical(fromHex('0xBep0'), 190.0)
1053 self.identical(fromHex('0xbEp0'), 190.0)
1054 self.identical(fromHex('0XBE0P-4'), 190.0)
1055 self.identical(fromHex('0xBEp0'), 190.0)
1056 self.identical(fromHex('0xB.Ep4'), 190.0)
1057 self.identical(fromHex('0x.BEp8'), 190.0)
1058 self.identical(fromHex('0x.0BEp12'), 190.0)
1059
1060 # moving the point around
1061 pi = fromHex('0x1.921fb54442d18p1')
1062 self.identical(fromHex('0x.006487ed5110b46p11'), pi)
1063 self.identical(fromHex('0x.00c90fdaa22168cp10'), pi)
1064 self.identical(fromHex('0x.01921fb54442d18p9'), pi)
1065 self.identical(fromHex('0x.03243f6a8885a3p8'), pi)
1066 self.identical(fromHex('0x.06487ed5110b46p7'), pi)
1067 self.identical(fromHex('0x.0c90fdaa22168cp6'), pi)
1068 self.identical(fromHex('0x.1921fb54442d18p5'), pi)
1069 self.identical(fromHex('0x.3243f6a8885a3p4'), pi)
1070 self.identical(fromHex('0x.6487ed5110b46p3'), pi)
1071 self.identical(fromHex('0x.c90fdaa22168cp2'), pi)
1072 self.identical(fromHex('0x1.921fb54442d18p1'), pi)
1073 self.identical(fromHex('0x3.243f6a8885a3p0'), pi)
1074 self.identical(fromHex('0x6.487ed5110b46p-1'), pi)
1075 self.identical(fromHex('0xc.90fdaa22168cp-2'), pi)
1076 self.identical(fromHex('0x19.21fb54442d18p-3'), pi)
1077 self.identical(fromHex('0x32.43f6a8885a3p-4'), pi)
1078 self.identical(fromHex('0x64.87ed5110b46p-5'), pi)
1079 self.identical(fromHex('0xc9.0fdaa22168cp-6'), pi)
1080 self.identical(fromHex('0x192.1fb54442d18p-7'), pi)
1081 self.identical(fromHex('0x324.3f6a8885a3p-8'), pi)
1082 self.identical(fromHex('0x648.7ed5110b46p-9'), pi)
1083 self.identical(fromHex('0xc90.fdaa22168cp-10'), pi)
1084 self.identical(fromHex('0x1921.fb54442d18p-11'), pi)
1085 # ...
1086 self.identical(fromHex('0x1921fb54442d1.8p-47'), pi)
1087 self.identical(fromHex('0x3243f6a8885a3p-48'), pi)
1088 self.identical(fromHex('0x6487ed5110b46p-49'), pi)
1089 self.identical(fromHex('0xc90fdaa22168cp-50'), pi)
1090 self.identical(fromHex('0x1921fb54442d18p-51'), pi)
1091 self.identical(fromHex('0x3243f6a8885a30p-52'), pi)
1092 self.identical(fromHex('0x6487ed5110b460p-53'), pi)
1093 self.identical(fromHex('0xc90fdaa22168c0p-54'), pi)
1094 self.identical(fromHex('0x1921fb54442d180p-55'), pi)
1095
1096
1097 # results that should overflow...
1098 self.assertRaises(OverflowError, fromHex, '-0x1p1024')
1099 self.assertRaises(OverflowError, fromHex, '0x1p+1025')
1100 self.assertRaises(OverflowError, fromHex, '+0X1p1030')
1101 self.assertRaises(OverflowError, fromHex, '-0x1p+1100')
1102 self.assertRaises(OverflowError, fromHex, '0X1p123456789123456789')
1103 self.assertRaises(OverflowError, fromHex, '+0X.8p+1025')
1104 self.assertRaises(OverflowError, fromHex, '+0x0.8p1025')
1105 self.assertRaises(OverflowError, fromHex, '-0x0.4p1026')
1106 self.assertRaises(OverflowError, fromHex, '0X2p+1023')
1107 self.assertRaises(OverflowError, fromHex, '0x2.p1023')
1108 self.assertRaises(OverflowError, fromHex, '-0x2.0p+1023')
1109 self.assertRaises(OverflowError, fromHex, '+0X4p+1022')
1110 self.assertRaises(OverflowError, fromHex, '0x1.ffffffffffffffp+1023')
1111 self.assertRaises(OverflowError, fromHex, '-0X1.fffffffffffff9p1023')
1112 self.assertRaises(OverflowError, fromHex, '0X1.fffffffffffff8p1023')
1113 self.assertRaises(OverflowError, fromHex, '+0x3.fffffffffffffp1022')
1114 self.assertRaises(OverflowError, fromHex, '0x3fffffffffffffp+970')
1115 self.assertRaises(OverflowError, fromHex, '0x10000000000000000p960')
1116 self.assertRaises(OverflowError, fromHex, '-0Xffffffffffffffffp960')
1117
1118 # ...and those that round to +-max float
1119 self.identical(fromHex('+0x1.fffffffffffffp+1023'), MAX)
1120 self.identical(fromHex('-0X1.fffffffffffff7p1023'), -MAX)
1121 self.identical(fromHex('0X1.fffffffffffff7fffffffffffffp1023'), MAX)
1122
1123 # zeros
1124 self.identical(fromHex('0x0p0'), 0.0)
1125 self.identical(fromHex('0x0p1000'), 0.0)
1126 self.identical(fromHex('-0x0p1023'), -0.0)
1127 self.identical(fromHex('0X0p1024'), 0.0)
1128 self.identical(fromHex('-0x0p1025'), -0.0)
1129 self.identical(fromHex('0X0p2000'), 0.0)
1130 self.identical(fromHex('0x0p123456789123456789'), 0.0)
1131 self.identical(fromHex('-0X0p-0'), -0.0)
1132 self.identical(fromHex('-0X0p-1000'), -0.0)
1133 self.identical(fromHex('0x0p-1023'), 0.0)
1134 self.identical(fromHex('-0X0p-1024'), -0.0)
1135 self.identical(fromHex('-0x0p-1025'), -0.0)
1136 self.identical(fromHex('-0x0p-1072'), -0.0)
1137 self.identical(fromHex('0X0p-1073'), 0.0)
1138 self.identical(fromHex('-0x0p-1074'), -0.0)
1139 self.identical(fromHex('0x0p-1075'), 0.0)
1140 self.identical(fromHex('0X0p-1076'), 0.0)
1141 self.identical(fromHex('-0X0p-2000'), -0.0)
1142 self.identical(fromHex('-0x0p-123456789123456789'), -0.0)
1143
1144 # values that should underflow to 0
1145 self.identical(fromHex('0X1p-1075'), 0.0)
1146 self.identical(fromHex('-0X1p-1075'), -0.0)
1147 self.identical(fromHex('-0x1p-123456789123456789'), -0.0)
1148 self.identical(fromHex('0x1.00000000000000001p-1075'), TINY)
1149 self.identical(fromHex('-0x1.1p-1075'), -TINY)
1150 self.identical(fromHex('0x1.fffffffffffffffffp-1075'), TINY)
1151
1152 # check round-half-even is working correctly near 0 ...
1153 self.identical(fromHex('0x1p-1076'), 0.0)
1154 self.identical(fromHex('0X2p-1076'), 0.0)
1155 self.identical(fromHex('0X3p-1076'), TINY)
1156 self.identical(fromHex('0x4p-1076'), TINY)
1157 self.identical(fromHex('0X5p-1076'), TINY)
1158 self.identical(fromHex('0X6p-1076'), 2*TINY)
1159 self.identical(fromHex('0x7p-1076'), 2*TINY)
1160 self.identical(fromHex('0X8p-1076'), 2*TINY)
1161 self.identical(fromHex('0X9p-1076'), 2*TINY)
1162 self.identical(fromHex('0xap-1076'), 2*TINY)
1163 self.identical(fromHex('0Xbp-1076'), 3*TINY)
1164 self.identical(fromHex('0xcp-1076'), 3*TINY)
1165 self.identical(fromHex('0Xdp-1076'), 3*TINY)
1166 self.identical(fromHex('0Xep-1076'), 4*TINY)
1167 self.identical(fromHex('0xfp-1076'), 4*TINY)
1168 self.identical(fromHex('0x10p-1076'), 4*TINY)
1169 self.identical(fromHex('-0x1p-1076'), -0.0)
1170 self.identical(fromHex('-0X2p-1076'), -0.0)
1171 self.identical(fromHex('-0x3p-1076'), -TINY)
1172 self.identical(fromHex('-0X4p-1076'), -TINY)
1173 self.identical(fromHex('-0x5p-1076'), -TINY)
1174 self.identical(fromHex('-0x6p-1076'), -2*TINY)
1175 self.identical(fromHex('-0X7p-1076'), -2*TINY)
1176 self.identical(fromHex('-0X8p-1076'), -2*TINY)
1177 self.identical(fromHex('-0X9p-1076'), -2*TINY)
1178 self.identical(fromHex('-0Xap-1076'), -2*TINY)
1179 self.identical(fromHex('-0xbp-1076'), -3*TINY)
1180 self.identical(fromHex('-0xcp-1076'), -3*TINY)
1181 self.identical(fromHex('-0Xdp-1076'), -3*TINY)
1182 self.identical(fromHex('-0xep-1076'), -4*TINY)
1183 self.identical(fromHex('-0Xfp-1076'), -4*TINY)
1184 self.identical(fromHex('-0X10p-1076'), -4*TINY)
1185
1186 # ... and near MIN ...
1187 self.identical(fromHex('0x0.ffffffffffffd6p-1022'), MIN-3*TINY)
1188 self.identical(fromHex('0x0.ffffffffffffd8p-1022'), MIN-2*TINY)
1189 self.identical(fromHex('0x0.ffffffffffffdap-1022'), MIN-2*TINY)
1190 self.identical(fromHex('0x0.ffffffffffffdcp-1022'), MIN-2*TINY)
1191 self.identical(fromHex('0x0.ffffffffffffdep-1022'), MIN-2*TINY)
1192 self.identical(fromHex('0x0.ffffffffffffe0p-1022'), MIN-2*TINY)
1193 self.identical(fromHex('0x0.ffffffffffffe2p-1022'), MIN-2*TINY)
1194 self.identical(fromHex('0x0.ffffffffffffe4p-1022'), MIN-2*TINY)
1195 self.identical(fromHex('0x0.ffffffffffffe6p-1022'), MIN-2*TINY)
1196 self.identical(fromHex('0x0.ffffffffffffe8p-1022'), MIN-2*TINY)
1197 self.identical(fromHex('0x0.ffffffffffffeap-1022'), MIN-TINY)
1198 self.identical(fromHex('0x0.ffffffffffffecp-1022'), MIN-TINY)
1199 self.identical(fromHex('0x0.ffffffffffffeep-1022'), MIN-TINY)
1200 self.identical(fromHex('0x0.fffffffffffff0p-1022'), MIN-TINY)
1201 self.identical(fromHex('0x0.fffffffffffff2p-1022'), MIN-TINY)
1202 self.identical(fromHex('0x0.fffffffffffff4p-1022'), MIN-TINY)
1203 self.identical(fromHex('0x0.fffffffffffff6p-1022'), MIN-TINY)
1204 self.identical(fromHex('0x0.fffffffffffff8p-1022'), MIN)
1205 self.identical(fromHex('0x0.fffffffffffffap-1022'), MIN)
1206 self.identical(fromHex('0x0.fffffffffffffcp-1022'), MIN)
1207 self.identical(fromHex('0x0.fffffffffffffep-1022'), MIN)
1208 self.identical(fromHex('0x1.00000000000000p-1022'), MIN)
1209 self.identical(fromHex('0x1.00000000000002p-1022'), MIN)
1210 self.identical(fromHex('0x1.00000000000004p-1022'), MIN)
1211 self.identical(fromHex('0x1.00000000000006p-1022'), MIN)
1212 self.identical(fromHex('0x1.00000000000008p-1022'), MIN)
1213 self.identical(fromHex('0x1.0000000000000ap-1022'), MIN+TINY)
1214 self.identical(fromHex('0x1.0000000000000cp-1022'), MIN+TINY)
1215 self.identical(fromHex('0x1.0000000000000ep-1022'), MIN+TINY)
1216 self.identical(fromHex('0x1.00000000000010p-1022'), MIN+TINY)
1217 self.identical(fromHex('0x1.00000000000012p-1022'), MIN+TINY)
1218 self.identical(fromHex('0x1.00000000000014p-1022'), MIN+TINY)
1219 self.identical(fromHex('0x1.00000000000016p-1022'), MIN+TINY)
1220 self.identical(fromHex('0x1.00000000000018p-1022'), MIN+2*TINY)
1221
1222 # ... and near 1.0.
1223 self.identical(fromHex('0x0.fffffffffffff0p0'), 1.0-EPS)
1224 self.identical(fromHex('0x0.fffffffffffff1p0'), 1.0-EPS)
1225 self.identical(fromHex('0X0.fffffffffffff2p0'), 1.0-EPS)
1226 self.identical(fromHex('0x0.fffffffffffff3p0'), 1.0-EPS)
1227 self.identical(fromHex('0X0.fffffffffffff4p0'), 1.0-EPS)
1228 self.identical(fromHex('0X0.fffffffffffff5p0'), 1.0-EPS/2)
1229 self.identical(fromHex('0X0.fffffffffffff6p0'), 1.0-EPS/2)
1230 self.identical(fromHex('0x0.fffffffffffff7p0'), 1.0-EPS/2)
1231 self.identical(fromHex('0x0.fffffffffffff8p0'), 1.0-EPS/2)
1232 self.identical(fromHex('0X0.fffffffffffff9p0'), 1.0-EPS/2)
1233 self.identical(fromHex('0X0.fffffffffffffap0'), 1.0-EPS/2)
1234 self.identical(fromHex('0x0.fffffffffffffbp0'), 1.0-EPS/2)
1235 self.identical(fromHex('0X0.fffffffffffffcp0'), 1.0)
1236 self.identical(fromHex('0x0.fffffffffffffdp0'), 1.0)
1237 self.identical(fromHex('0X0.fffffffffffffep0'), 1.0)
1238 self.identical(fromHex('0x0.ffffffffffffffp0'), 1.0)
1239 self.identical(fromHex('0X1.00000000000000p0'), 1.0)
1240 self.identical(fromHex('0X1.00000000000001p0'), 1.0)
1241 self.identical(fromHex('0x1.00000000000002p0'), 1.0)
1242 self.identical(fromHex('0X1.00000000000003p0'), 1.0)
1243 self.identical(fromHex('0x1.00000000000004p0'), 1.0)
1244 self.identical(fromHex('0X1.00000000000005p0'), 1.0)
1245 self.identical(fromHex('0X1.00000000000006p0'), 1.0)
1246 self.identical(fromHex('0X1.00000000000007p0'), 1.0)
1247 self.identical(fromHex('0x1.00000000000007ffffffffffffffffffffp0'),
1248 1.0)
1249 self.identical(fromHex('0x1.00000000000008p0'), 1.0)
1250 self.identical(fromHex('0x1.00000000000008000000000000000001p0'),
1251 1+EPS)
1252 self.identical(fromHex('0X1.00000000000009p0'), 1.0+EPS)
1253 self.identical(fromHex('0x1.0000000000000ap0'), 1.0+EPS)
1254 self.identical(fromHex('0x1.0000000000000bp0'), 1.0+EPS)
1255 self.identical(fromHex('0X1.0000000000000cp0'), 1.0+EPS)
1256 self.identical(fromHex('0x1.0000000000000dp0'), 1.0+EPS)
1257 self.identical(fromHex('0x1.0000000000000ep0'), 1.0+EPS)
1258 self.identical(fromHex('0X1.0000000000000fp0'), 1.0+EPS)
1259 self.identical(fromHex('0x1.00000000000010p0'), 1.0+EPS)
1260 self.identical(fromHex('0X1.00000000000011p0'), 1.0+EPS)
1261 self.identical(fromHex('0x1.00000000000012p0'), 1.0+EPS)
1262 self.identical(fromHex('0X1.00000000000013p0'), 1.0+EPS)
1263 self.identical(fromHex('0X1.00000000000014p0'), 1.0+EPS)
1264 self.identical(fromHex('0x1.00000000000015p0'), 1.0+EPS)
1265 self.identical(fromHex('0x1.00000000000016p0'), 1.0+EPS)
1266 self.identical(fromHex('0X1.00000000000017p0'), 1.0+EPS)
1267 self.identical(fromHex('0x1.00000000000017ffffffffffffffffffffp0'),
1268 1.0+EPS)
1269 self.identical(fromHex('0x1.00000000000018p0'), 1.0+2*EPS)
1270 self.identical(fromHex('0X1.00000000000018000000000000000001p0'),
1271 1.0+2*EPS)
1272 self.identical(fromHex('0x1.00000000000019p0'), 1.0+2*EPS)
1273 self.identical(fromHex('0X1.0000000000001ap0'), 1.0+2*EPS)
1274 self.identical(fromHex('0X1.0000000000001bp0'), 1.0+2*EPS)
1275 self.identical(fromHex('0x1.0000000000001cp0'), 1.0+2*EPS)
1276 self.identical(fromHex('0x1.0000000000001dp0'), 1.0+2*EPS)
1277 self.identical(fromHex('0x1.0000000000001ep0'), 1.0+2*EPS)
1278 self.identical(fromHex('0X1.0000000000001fp0'), 1.0+2*EPS)
1279 self.identical(fromHex('0x1.00000000000020p0'), 1.0+2*EPS)
1280
1281 def test_roundtrip(self):
1282 def roundtrip(x):
1283 return fromHex(toHex(x))
1284
1285 for x in [NAN, INF, self.MAX, self.MIN, self.MIN-self.TINY, self.TINY, 0.0]:
1286 self.identical(x, roundtrip(x))
1287 self.identical(-x, roundtrip(-x))
1288
1289 # fromHex(toHex(x)) should exactly recover x, for any non-NaN float x.
1290 import random
1291 for i in xrange(10000):
1292 e = random.randrange(-1200, 1200)
1293 m = random.random()
1294 s = random.choice([1.0, -1.0])
1295 try:
1296 x = s*ldexp(m, e)
1297 except OverflowError:
1298 pass
1299 else:
1300 self.identical(x, fromHex(toHex(x)))
1301
Christian Heimes6f341092008-04-18 23:13:07 +00001302
Michael W. Hudsonba283e22005-05-27 15:23:20 +00001303def test_main():
1304 test_support.run_unittest(
Amaury Forgeot d'Arcfeb8cad2008-09-06 20:53:51 +00001305 GeneralFloatCases,
Michael W. Hudsonba283e22005-05-27 15:23:20 +00001306 FormatFunctionsTestCase,
1307 UnknownFormatTestCase,
Christian Heimes284d9272007-12-10 22:28:56 +00001308 IEEEFormatTestCase,
Christian Heimes0a8143f2007-12-18 23:22:54 +00001309 ReprTestCase,
Mark Dickinsonbd15a062009-11-18 19:33:35 +00001310 RoundTestCase,
Christian Heimes0a8143f2007-12-18 23:22:54 +00001311 InfNanTest,
Mark Dickinson7103aa42008-07-15 19:08:33 +00001312 HexFloatTestCase,
Christian Heimesf15c66e2007-12-11 00:54:34 +00001313 )
Michael W. Hudsonba283e22005-05-27 15:23:20 +00001314
1315if __name__ == '__main__':
1316 test_main()