blob: 5932b964da596598e6bafabfefb2fa4f26b119fd [file] [log] [blame]
Michael W. Hudsonba283e22005-05-27 15:23:20 +00001
2import unittest, struct
Christian Heimes827b35c2007-12-10 22:19:17 +00003import os
Eric Smith0923d1d2009-04-16 20:16:10 +00004import sys
Benjamin Petersonee8712c2008-05-20 21:35:26 +00005from test import support
Christian Heimes53876d92008-04-19 00:31:39 +00006import math
Mark Dickinson65fe25e2008-07-16 11:30:51 +00007from math import isinf, isnan, copysign, ldexp
Christian Heimes53876d92008-04-19 00:31:39 +00008import operator
Amaury Forgeot d'Arc7e958d12008-09-06 21:03:22 +00009import random, fractions
Michael W. Hudsonba283e22005-05-27 15:23:20 +000010
Christian Heimes53876d92008-04-19 00:31:39 +000011INF = float("inf")
12NAN = float("nan")
Christian Heimes99170a52007-12-19 02:07:34 +000013
Mark Dickinson9ab44b52009-12-30 16:22:49 +000014# decorator for skipping tests on non-IEEE 754 platforms
15requires_IEEE_754 = unittest.skipUnless(
16 float.__getformat__("double").startswith("IEEE"),
17 "test requires IEEE 754 doubles")
18
Eric Smith0923d1d2009-04-16 20:16:10 +000019#locate file with float format test values
20test_dir = os.path.dirname(__file__) or os.curdir
21format_testfile = os.path.join(test_dir, 'formatfloat_testcases.txt')
22
Christian Heimes81ee3ef2008-05-04 22:42:01 +000023class GeneralFloatCases(unittest.TestCase):
24
25 def test_float(self):
26 self.assertEqual(float(3.14), 3.14)
27 self.assertEqual(float(314), 314.0)
28 self.assertEqual(float(" 3.14 "), 3.14)
Amaury Forgeot d'Arc7e958d12008-09-06 21:03:22 +000029 self.assertEqual(float(b" 3.14 "), 3.14)
Christian Heimes81ee3ef2008-05-04 22:42:01 +000030 self.assertRaises(ValueError, float, " 0x3.1 ")
31 self.assertRaises(ValueError, float, " -0x3.p-1 ")
32 self.assertRaises(ValueError, float, " +0x3.p-1 ")
33 self.assertRaises(ValueError, float, "++3.14")
34 self.assertRaises(ValueError, float, "+-3.14")
35 self.assertRaises(ValueError, float, "-+3.14")
36 self.assertRaises(ValueError, float, "--3.14")
Eric Smith0923d1d2009-04-16 20:16:10 +000037 self.assertRaises(ValueError, float, ".nan")
38 self.assertRaises(ValueError, float, "+.inf")
39 self.assertRaises(ValueError, float, ".")
40 self.assertRaises(ValueError, float, "-.")
Mark Dickinsonc2d86892010-02-12 21:18:34 +000041 # check that we don't accept alternate exponent markers
42 self.assertRaises(ValueError, float, "-1.7d29")
43 self.assertRaises(ValueError, float, "3D-14")
Amaury Forgeot d'Arc7e958d12008-09-06 21:03:22 +000044 self.assertEqual(float(b" \u0663.\u0661\u0664 ".decode('raw-unicode-escape')), 3.14)
Mark Dickinsona9023be2009-10-27 22:12:20 +000045 # extra long strings should not be a problem
46 float(b'.' + b'1'*1000)
47 float('.' + '1'*1000)
Christian Heimes81ee3ef2008-05-04 22:42:01 +000048
Benjamin Petersonee8712c2008-05-20 21:35:26 +000049 @support.run_with_locale('LC_NUMERIC', 'fr_FR', 'de_DE')
Christian Heimes81ee3ef2008-05-04 22:42:01 +000050 def test_float_with_comma(self):
51 # set locale to something that doesn't use '.' for the decimal point
52 # float must not accept the locale specific decimal point but
53 # it still has to accept the normal python syntac
54 import locale
55 if not locale.localeconv()['decimal_point'] == ',':
56 return
57
58 self.assertEqual(float(" 3.14 "), 3.14)
59 self.assertEqual(float("+3.14 "), 3.14)
60 self.assertEqual(float("-3.14 "), -3.14)
61 self.assertEqual(float(".14 "), .14)
62 self.assertEqual(float("3. "), 3.0)
63 self.assertEqual(float("3.e3 "), 3000.0)
64 self.assertEqual(float("3.2e3 "), 3200.0)
65 self.assertEqual(float("2.5e-1 "), 0.25)
66 self.assertEqual(float("5e-1"), 0.5)
67 self.assertRaises(ValueError, float, " 3,14 ")
68 self.assertRaises(ValueError, float, " +3,14 ")
69 self.assertRaises(ValueError, float, " -3,14 ")
70 self.assertRaises(ValueError, float, " 0x3.1 ")
71 self.assertRaises(ValueError, float, " -0x3.p-1 ")
72 self.assertRaises(ValueError, float, " +0x3.p-1 ")
73 self.assertEqual(float(" 25.e-1 "), 2.5)
Benjamin Petersond43029b2008-09-06 23:33:21 +000074 self.assertEqual(support.fcmp(float(" .25e-1 "), .025), 0)
Christian Heimes81ee3ef2008-05-04 22:42:01 +000075
76 def test_floatconversion(self):
77 # Make sure that calls to __float__() work properly
78 class Foo0:
79 def __float__(self):
80 return 42.
81
82 class Foo1(object):
83 def __float__(self):
84 return 42.
85
86 class Foo2(float):
87 def __float__(self):
88 return 42.
89
90 class Foo3(float):
91 def __new__(cls, value=0.):
92 return float.__new__(cls, 2*value)
93
94 def __float__(self):
95 return self
96
97 class Foo4(float):
98 def __float__(self):
99 return 42
100
Benjamin Peterson2808d3c2009-04-15 21:34:27 +0000101 # Issue 5759: __float__ not called on str subclasses (though it is on
102 # unicode subclasses).
103 class FooStr(str):
104 def __float__(self):
105 return float(str(self)) + 1
106
Christian Heimes81ee3ef2008-05-04 22:42:01 +0000107 self.assertAlmostEqual(float(Foo0()), 42.)
108 self.assertAlmostEqual(float(Foo1()), 42.)
109 self.assertAlmostEqual(float(Foo2()), 42.)
110 self.assertAlmostEqual(float(Foo3(21)), 42.)
111 self.assertRaises(TypeError, float, Foo4(42))
Benjamin Peterson2808d3c2009-04-15 21:34:27 +0000112 self.assertAlmostEqual(float(FooStr('8')), 9.)
Christian Heimes81ee3ef2008-05-04 22:42:01 +0000113
114 def test_floatasratio(self):
115 for f, ratio in [
116 (0.875, (7, 8)),
117 (-0.875, (-7, 8)),
118 (0.0, (0, 1)),
119 (11.5, (23, 2)),
120 ]:
121 self.assertEqual(f.as_integer_ratio(), ratio)
122
123 for i in range(10000):
124 f = random.random()
125 f *= 10 ** random.randint(-100, 100)
126 n, d = f.as_integer_ratio()
127 self.assertEqual(float(n).__truediv__(d), f)
128
129 R = fractions.Fraction
130 self.assertEqual(R(0, 1),
131 R(*float(0.0).as_integer_ratio()))
132 self.assertEqual(R(5, 2),
133 R(*float(2.5).as_integer_ratio()))
134 self.assertEqual(R(1, 2),
135 R(*float(0.5).as_integer_ratio()))
136 self.assertEqual(R(4728779608739021, 2251799813685248),
137 R(*float(2.1).as_integer_ratio()))
138 self.assertEqual(R(-4728779608739021, 2251799813685248),
139 R(*float(-2.1).as_integer_ratio()))
140 self.assertEqual(R(-2100, 1),
141 R(*float(-2100.0).as_integer_ratio()))
142
143 self.assertRaises(OverflowError, float('inf').as_integer_ratio)
144 self.assertRaises(OverflowError, float('-inf').as_integer_ratio)
145 self.assertRaises(ValueError, float('nan').as_integer_ratio)
146
Mark Dickinson4a1f5932008-11-12 23:23:36 +0000147 def test_float_containment(self):
148 floats = (INF, -INF, 0.0, 1.0, NAN)
149 for f in floats:
Benjamin Peterson577473f2010-01-19 00:09:57 +0000150 self.assertIn(f, [f])
Benjamin Peterson577473f2010-01-19 00:09:57 +0000151 self.assertIn(f, (f,))
Benjamin Peterson577473f2010-01-19 00:09:57 +0000152 self.assertIn(f, {f})
Benjamin Peterson577473f2010-01-19 00:09:57 +0000153 self.assertIn(f, {f: None})
Mark Dickinson4a1f5932008-11-12 23:23:36 +0000154 self.assertEqual([f].count(f), 1, "[].count('%r') != 1" % f)
Benjamin Peterson577473f2010-01-19 00:09:57 +0000155 self.assertIn(f, floats)
Mark Dickinson4a1f5932008-11-12 23:23:36 +0000156
157 for f in floats:
158 # nonidentical containers, same type, same contents
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000159 self.assertTrue([f] == [f], "[%r] != [%r]" % (f, f))
160 self.assertTrue((f,) == (f,), "(%r,) != (%r,)" % (f, f))
161 self.assertTrue({f} == {f}, "{%r} != {%r}" % (f, f))
162 self.assertTrue({f : None} == {f: None}, "{%r : None} != "
Mark Dickinson4a1f5932008-11-12 23:23:36 +0000163 "{%r : None}" % (f, f))
164
165 # identical containers
166 l, t, s, d = [f], (f,), {f}, {f: None}
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000167 self.assertTrue(l == l, "[%r] not equal to itself" % f)
168 self.assertTrue(t == t, "(%r,) not equal to itself" % f)
169 self.assertTrue(s == s, "{%r} not equal to itself" % f)
170 self.assertTrue(d == d, "{%r : None} not equal to itself" % f)
Mark Dickinson4a1f5932008-11-12 23:23:36 +0000171
Mark Dickinson9ab44b52009-12-30 16:22:49 +0000172 def assertEqualAndEqualSign(self, a, b):
173 # fail unless a == b and a and b have the same sign bit;
174 # the only difference from assertEqual is that this test
175 # distingishes -0.0 and 0.0.
176 self.assertEqual((a, copysign(1.0, a)), (b, copysign(1.0, b)))
177
178 @requires_IEEE_754
179 def test_float_pow(self):
180 # test builtin pow and ** operator for IEEE 754 special cases.
181 # Special cases taken from section F.9.4.4 of the C99 specification
182
183 for pow_op in pow, operator.pow:
184 # x**NAN is NAN for any x except 1
185 self.assertTrue(isnan(pow_op(-INF, NAN)))
186 self.assertTrue(isnan(pow_op(-2.0, NAN)))
187 self.assertTrue(isnan(pow_op(-1.0, NAN)))
188 self.assertTrue(isnan(pow_op(-0.5, NAN)))
189 self.assertTrue(isnan(pow_op(-0.0, NAN)))
190 self.assertTrue(isnan(pow_op(0.0, NAN)))
191 self.assertTrue(isnan(pow_op(0.5, NAN)))
192 self.assertTrue(isnan(pow_op(2.0, NAN)))
193 self.assertTrue(isnan(pow_op(INF, NAN)))
194 self.assertTrue(isnan(pow_op(NAN, NAN)))
195
196 # NAN**y is NAN for any y except +-0
197 self.assertTrue(isnan(pow_op(NAN, -INF)))
198 self.assertTrue(isnan(pow_op(NAN, -2.0)))
199 self.assertTrue(isnan(pow_op(NAN, -1.0)))
200 self.assertTrue(isnan(pow_op(NAN, -0.5)))
201 self.assertTrue(isnan(pow_op(NAN, 0.5)))
202 self.assertTrue(isnan(pow_op(NAN, 1.0)))
203 self.assertTrue(isnan(pow_op(NAN, 2.0)))
204 self.assertTrue(isnan(pow_op(NAN, INF)))
205
206 # (+-0)**y raises ZeroDivisionError for y a negative odd integer
207 self.assertRaises(ZeroDivisionError, pow_op, -0.0, -1.0)
208 self.assertRaises(ZeroDivisionError, pow_op, 0.0, -1.0)
209
210 # (+-0)**y raises ZeroDivisionError for y finite and negative
211 # but not an odd integer
212 self.assertRaises(ZeroDivisionError, pow_op, -0.0, -2.0)
213 self.assertRaises(ZeroDivisionError, pow_op, -0.0, -0.5)
214 self.assertRaises(ZeroDivisionError, pow_op, 0.0, -2.0)
215 self.assertRaises(ZeroDivisionError, pow_op, 0.0, -0.5)
216
217 # (+-0)**y is +-0 for y a positive odd integer
218 self.assertEqualAndEqualSign(pow_op(-0.0, 1.0), -0.0)
219 self.assertEqualAndEqualSign(pow_op(0.0, 1.0), 0.0)
220
221 # (+-0)**y is 0 for y finite and positive but not an odd integer
222 self.assertEqualAndEqualSign(pow_op(-0.0, 0.5), 0.0)
223 self.assertEqualAndEqualSign(pow_op(-0.0, 2.0), 0.0)
224 self.assertEqualAndEqualSign(pow_op(0.0, 0.5), 0.0)
225 self.assertEqualAndEqualSign(pow_op(0.0, 2.0), 0.0)
226
227 # (-1)**+-inf is 1
228 self.assertEqualAndEqualSign(pow_op(-1.0, -INF), 1.0)
229 self.assertEqualAndEqualSign(pow_op(-1.0, INF), 1.0)
230
231 # 1**y is 1 for any y, even if y is an infinity or nan
232 self.assertEqualAndEqualSign(pow_op(1.0, -INF), 1.0)
233 self.assertEqualAndEqualSign(pow_op(1.0, -2.0), 1.0)
234 self.assertEqualAndEqualSign(pow_op(1.0, -1.0), 1.0)
235 self.assertEqualAndEqualSign(pow_op(1.0, -0.5), 1.0)
236 self.assertEqualAndEqualSign(pow_op(1.0, -0.0), 1.0)
237 self.assertEqualAndEqualSign(pow_op(1.0, 0.0), 1.0)
238 self.assertEqualAndEqualSign(pow_op(1.0, 0.5), 1.0)
239 self.assertEqualAndEqualSign(pow_op(1.0, 1.0), 1.0)
240 self.assertEqualAndEqualSign(pow_op(1.0, 2.0), 1.0)
241 self.assertEqualAndEqualSign(pow_op(1.0, INF), 1.0)
242 self.assertEqualAndEqualSign(pow_op(1.0, NAN), 1.0)
243
244 # x**+-0 is 1 for any x, even if x is a zero, infinity, or nan
245 self.assertEqualAndEqualSign(pow_op(-INF, 0.0), 1.0)
246 self.assertEqualAndEqualSign(pow_op(-2.0, 0.0), 1.0)
247 self.assertEqualAndEqualSign(pow_op(-1.0, 0.0), 1.0)
248 self.assertEqualAndEqualSign(pow_op(-0.5, 0.0), 1.0)
249 self.assertEqualAndEqualSign(pow_op(-0.0, 0.0), 1.0)
250 self.assertEqualAndEqualSign(pow_op(0.0, 0.0), 1.0)
251 self.assertEqualAndEqualSign(pow_op(0.5, 0.0), 1.0)
252 self.assertEqualAndEqualSign(pow_op(1.0, 0.0), 1.0)
253 self.assertEqualAndEqualSign(pow_op(2.0, 0.0), 1.0)
254 self.assertEqualAndEqualSign(pow_op(INF, 0.0), 1.0)
255 self.assertEqualAndEqualSign(pow_op(NAN, 0.0), 1.0)
256 self.assertEqualAndEqualSign(pow_op(-INF, -0.0), 1.0)
257 self.assertEqualAndEqualSign(pow_op(-2.0, -0.0), 1.0)
258 self.assertEqualAndEqualSign(pow_op(-1.0, -0.0), 1.0)
259 self.assertEqualAndEqualSign(pow_op(-0.5, -0.0), 1.0)
260 self.assertEqualAndEqualSign(pow_op(-0.0, -0.0), 1.0)
261 self.assertEqualAndEqualSign(pow_op(0.0, -0.0), 1.0)
262 self.assertEqualAndEqualSign(pow_op(0.5, -0.0), 1.0)
263 self.assertEqualAndEqualSign(pow_op(1.0, -0.0), 1.0)
264 self.assertEqualAndEqualSign(pow_op(2.0, -0.0), 1.0)
265 self.assertEqualAndEqualSign(pow_op(INF, -0.0), 1.0)
266 self.assertEqualAndEqualSign(pow_op(NAN, -0.0), 1.0)
267
268 # x**y defers to complex pow for finite negative x and
269 # non-integral y.
270 self.assertEqual(type(pow_op(-2.0, -0.5)), complex)
271 self.assertEqual(type(pow_op(-2.0, 0.5)), complex)
272 self.assertEqual(type(pow_op(-1.0, -0.5)), complex)
273 self.assertEqual(type(pow_op(-1.0, 0.5)), complex)
274 self.assertEqual(type(pow_op(-0.5, -0.5)), complex)
275 self.assertEqual(type(pow_op(-0.5, 0.5)), complex)
276
277 # x**-INF is INF for abs(x) < 1
278 self.assertEqualAndEqualSign(pow_op(-0.5, -INF), INF)
279 self.assertEqualAndEqualSign(pow_op(-0.0, -INF), INF)
280 self.assertEqualAndEqualSign(pow_op(0.0, -INF), INF)
281 self.assertEqualAndEqualSign(pow_op(0.5, -INF), INF)
282
283 # x**-INF is 0 for abs(x) > 1
284 self.assertEqualAndEqualSign(pow_op(-INF, -INF), 0.0)
285 self.assertEqualAndEqualSign(pow_op(-2.0, -INF), 0.0)
286 self.assertEqualAndEqualSign(pow_op(2.0, -INF), 0.0)
287 self.assertEqualAndEqualSign(pow_op(INF, -INF), 0.0)
288
289 # x**INF is 0 for abs(x) < 1
290 self.assertEqualAndEqualSign(pow_op(-0.5, INF), 0.0)
291 self.assertEqualAndEqualSign(pow_op(-0.0, INF), 0.0)
292 self.assertEqualAndEqualSign(pow_op(0.0, INF), 0.0)
293 self.assertEqualAndEqualSign(pow_op(0.5, INF), 0.0)
294
295 # x**INF is INF for abs(x) > 1
296 self.assertEqualAndEqualSign(pow_op(-INF, INF), INF)
297 self.assertEqualAndEqualSign(pow_op(-2.0, INF), INF)
298 self.assertEqualAndEqualSign(pow_op(2.0, INF), INF)
299 self.assertEqualAndEqualSign(pow_op(INF, INF), INF)
300
301 # (-INF)**y is -0.0 for y a negative odd integer
302 self.assertEqualAndEqualSign(pow_op(-INF, -1.0), -0.0)
303
304 # (-INF)**y is 0.0 for y negative but not an odd integer
305 self.assertEqualAndEqualSign(pow_op(-INF, -0.5), 0.0)
306 self.assertEqualAndEqualSign(pow_op(-INF, -2.0), 0.0)
307
308 # (-INF)**y is -INF for y a positive odd integer
309 self.assertEqualAndEqualSign(pow_op(-INF, 1.0), -INF)
310
311 # (-INF)**y is INF for y positive but not an odd integer
312 self.assertEqualAndEqualSign(pow_op(-INF, 0.5), INF)
313 self.assertEqualAndEqualSign(pow_op(-INF, 2.0), INF)
314
315 # INF**y is INF for y positive
316 self.assertEqualAndEqualSign(pow_op(INF, 0.5), INF)
317 self.assertEqualAndEqualSign(pow_op(INF, 1.0), INF)
318 self.assertEqualAndEqualSign(pow_op(INF, 2.0), INF)
319
320 # INF**y is 0.0 for y negative
321 self.assertEqualAndEqualSign(pow_op(INF, -2.0), 0.0)
322 self.assertEqualAndEqualSign(pow_op(INF, -1.0), 0.0)
323 self.assertEqualAndEqualSign(pow_op(INF, -0.5), 0.0)
324
325 # basic checks not covered by the special cases above
326 self.assertEqualAndEqualSign(pow_op(-2.0, -2.0), 0.25)
327 self.assertEqualAndEqualSign(pow_op(-2.0, -1.0), -0.5)
328 self.assertEqualAndEqualSign(pow_op(-2.0, -0.0), 1.0)
329 self.assertEqualAndEqualSign(pow_op(-2.0, 0.0), 1.0)
330 self.assertEqualAndEqualSign(pow_op(-2.0, 1.0), -2.0)
331 self.assertEqualAndEqualSign(pow_op(-2.0, 2.0), 4.0)
332 self.assertEqualAndEqualSign(pow_op(-1.0, -2.0), 1.0)
333 self.assertEqualAndEqualSign(pow_op(-1.0, -1.0), -1.0)
334 self.assertEqualAndEqualSign(pow_op(-1.0, -0.0), 1.0)
335 self.assertEqualAndEqualSign(pow_op(-1.0, 0.0), 1.0)
336 self.assertEqualAndEqualSign(pow_op(-1.0, 1.0), -1.0)
337 self.assertEqualAndEqualSign(pow_op(-1.0, 2.0), 1.0)
338 self.assertEqualAndEqualSign(pow_op(2.0, -2.0), 0.25)
339 self.assertEqualAndEqualSign(pow_op(2.0, -1.0), 0.5)
340 self.assertEqualAndEqualSign(pow_op(2.0, -0.0), 1.0)
341 self.assertEqualAndEqualSign(pow_op(2.0, 0.0), 1.0)
342 self.assertEqualAndEqualSign(pow_op(2.0, 1.0), 2.0)
343 self.assertEqualAndEqualSign(pow_op(2.0, 2.0), 4.0)
344
345 # 1 ** large and -1 ** large; some libms apparently
346 # have problems with these
347 self.assertEqualAndEqualSign(pow_op(1.0, -1e100), 1.0)
348 self.assertEqualAndEqualSign(pow_op(1.0, 1e100), 1.0)
349 self.assertEqualAndEqualSign(pow_op(-1.0, -1e100), 1.0)
350 self.assertEqualAndEqualSign(pow_op(-1.0, 1e100), 1.0)
351
352 # check sign for results that underflow to 0
353 self.assertEqualAndEqualSign(pow_op(-2.0, -2000.0), 0.0)
354 self.assertEqual(type(pow_op(-2.0, -2000.5)), complex)
355 self.assertEqualAndEqualSign(pow_op(-2.0, -2001.0), -0.0)
356 self.assertEqualAndEqualSign(pow_op(2.0, -2000.0), 0.0)
357 self.assertEqualAndEqualSign(pow_op(2.0, -2000.5), 0.0)
358 self.assertEqualAndEqualSign(pow_op(2.0, -2001.0), 0.0)
359 self.assertEqualAndEqualSign(pow_op(-0.5, 2000.0), 0.0)
360 self.assertEqual(type(pow_op(-0.5, 2000.5)), complex)
361 self.assertEqualAndEqualSign(pow_op(-0.5, 2001.0), -0.0)
362 self.assertEqualAndEqualSign(pow_op(0.5, 2000.0), 0.0)
363 self.assertEqualAndEqualSign(pow_op(0.5, 2000.5), 0.0)
364 self.assertEqualAndEqualSign(pow_op(0.5, 2001.0), 0.0)
365
366 # check we don't raise an exception for subnormal results,
367 # and validate signs. Tests currently disabled, since
368 # they fail on systems where a subnormal result from pow
369 # is flushed to zero (e.g. Debian/ia64.)
370 #self.assertTrue(0.0 < pow_op(0.5, 1048) < 1e-315)
371 #self.assertTrue(0.0 < pow_op(-0.5, 1048) < 1e-315)
372 #self.assertTrue(0.0 < pow_op(0.5, 1047) < 1e-315)
373 #self.assertTrue(0.0 > pow_op(-0.5, 1047) > -1e-315)
374 #self.assertTrue(0.0 < pow_op(2.0, -1048) < 1e-315)
375 #self.assertTrue(0.0 < pow_op(-2.0, -1048) < 1e-315)
376 #self.assertTrue(0.0 < pow_op(2.0, -1047) < 1e-315)
377 #self.assertTrue(0.0 > pow_op(-2.0, -1047) > -1e-315)
Mark Dickinson4a1f5932008-11-12 23:23:36 +0000378
379
Michael W. Hudsonba283e22005-05-27 15:23:20 +0000380class FormatFunctionsTestCase(unittest.TestCase):
381
382 def setUp(self):
383 self.save_formats = {'double':float.__getformat__('double'),
384 'float':float.__getformat__('float')}
385
386 def tearDown(self):
387 float.__setformat__('double', self.save_formats['double'])
388 float.__setformat__('float', self.save_formats['float'])
389
390 def test_getformat(self):
Ezio Melottib58e0bd2010-01-23 15:40:09 +0000391 self.assertIn(float.__getformat__('double'),
392 ['unknown', 'IEEE, big-endian', 'IEEE, little-endian'])
393 self.assertIn(float.__getformat__('float'),
394 ['unknown', 'IEEE, big-endian', 'IEEE, little-endian'])
Michael W. Hudsonba283e22005-05-27 15:23:20 +0000395 self.assertRaises(ValueError, float.__getformat__, 'chicken')
396 self.assertRaises(TypeError, float.__getformat__, 1)
397
398 def test_setformat(self):
399 for t in 'double', 'float':
400 float.__setformat__(t, 'unknown')
401 if self.save_formats[t] == 'IEEE, big-endian':
402 self.assertRaises(ValueError, float.__setformat__,
403 t, 'IEEE, little-endian')
404 elif self.save_formats[t] == 'IEEE, little-endian':
405 self.assertRaises(ValueError, float.__setformat__,
406 t, 'IEEE, big-endian')
407 else:
408 self.assertRaises(ValueError, float.__setformat__,
409 t, 'IEEE, big-endian')
410 self.assertRaises(ValueError, float.__setformat__,
411 t, 'IEEE, little-endian')
412 self.assertRaises(ValueError, float.__setformat__,
413 t, 'chicken')
414 self.assertRaises(ValueError, float.__setformat__,
415 'chicken', 'unknown')
416
Guido van Rossum2be161d2007-05-15 20:43:51 +0000417BE_DOUBLE_INF = b'\x7f\xf0\x00\x00\x00\x00\x00\x00'
Guido van Rossum254348e2007-11-21 19:29:53 +0000418LE_DOUBLE_INF = bytes(reversed(BE_DOUBLE_INF))
Guido van Rossum2be161d2007-05-15 20:43:51 +0000419BE_DOUBLE_NAN = b'\x7f\xf8\x00\x00\x00\x00\x00\x00'
Guido van Rossum254348e2007-11-21 19:29:53 +0000420LE_DOUBLE_NAN = bytes(reversed(BE_DOUBLE_NAN))
Michael W. Hudsonba283e22005-05-27 15:23:20 +0000421
Guido van Rossum2be161d2007-05-15 20:43:51 +0000422BE_FLOAT_INF = b'\x7f\x80\x00\x00'
Guido van Rossum254348e2007-11-21 19:29:53 +0000423LE_FLOAT_INF = bytes(reversed(BE_FLOAT_INF))
Guido van Rossum2be161d2007-05-15 20:43:51 +0000424BE_FLOAT_NAN = b'\x7f\xc0\x00\x00'
Guido van Rossum254348e2007-11-21 19:29:53 +0000425LE_FLOAT_NAN = bytes(reversed(BE_FLOAT_NAN))
Michael W. Hudsonba283e22005-05-27 15:23:20 +0000426
427# on non-IEEE platforms, attempting to unpack a bit pattern
428# representing an infinity or a NaN should raise an exception.
429
430class UnknownFormatTestCase(unittest.TestCase):
431 def setUp(self):
432 self.save_formats = {'double':float.__getformat__('double'),
433 'float':float.__getformat__('float')}
434 float.__setformat__('double', 'unknown')
435 float.__setformat__('float', 'unknown')
Tim Peters5d36a552005-06-03 22:40:27 +0000436
Michael W. Hudsonba283e22005-05-27 15:23:20 +0000437 def tearDown(self):
438 float.__setformat__('double', self.save_formats['double'])
439 float.__setformat__('float', self.save_formats['float'])
440
441 def test_double_specials_dont_unpack(self):
442 for fmt, data in [('>d', BE_DOUBLE_INF),
443 ('>d', BE_DOUBLE_NAN),
444 ('<d', LE_DOUBLE_INF),
445 ('<d', LE_DOUBLE_NAN)]:
446 self.assertRaises(ValueError, struct.unpack, fmt, data)
447
448 def test_float_specials_dont_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 self.assertRaises(ValueError, struct.unpack, fmt, data)
454
455
456# on an IEEE platform, all we guarantee is that bit patterns
457# representing infinities or NaNs do not raise an exception; all else
458# is accident (today).
Guido van Rossum04110fb2007-08-24 16:32:05 +0000459# let's also try to guarantee that -0.0 and 0.0 don't get confused.
Michael W. Hudsonba283e22005-05-27 15:23:20 +0000460
461class IEEEFormatTestCase(unittest.TestCase):
462 if float.__getformat__("double").startswith("IEEE"):
463 def test_double_specials_do_unpack(self):
464 for fmt, data in [('>d', BE_DOUBLE_INF),
465 ('>d', BE_DOUBLE_NAN),
466 ('<d', LE_DOUBLE_INF),
467 ('<d', LE_DOUBLE_NAN)]:
468 struct.unpack(fmt, data)
469
470 if float.__getformat__("float").startswith("IEEE"):
471 def test_float_specials_do_unpack(self):
472 for fmt, data in [('>f', BE_FLOAT_INF),
473 ('>f', BE_FLOAT_NAN),
474 ('<f', LE_FLOAT_INF),
475 ('<f', LE_FLOAT_NAN)]:
476 struct.unpack(fmt, data)
477
Guido van Rossum04110fb2007-08-24 16:32:05 +0000478 if float.__getformat__("double").startswith("IEEE"):
479 def test_negative_zero(self):
Guido van Rossum04110fb2007-08-24 16:32:05 +0000480 def pos_pos():
481 return 0.0, math.atan2(0.0, -1)
482 def pos_neg():
483 return 0.0, math.atan2(-0.0, -1)
484 def neg_pos():
485 return -0.0, math.atan2(0.0, -1)
486 def neg_neg():
487 return -0.0, math.atan2(-0.0, -1)
488 self.assertEquals(pos_pos(), neg_pos())
489 self.assertEquals(pos_neg(), neg_neg())
490
Eric Smith8c663262007-08-25 02:26:07 +0000491class FormatTestCase(unittest.TestCase):
Eric Smith11fe3e02007-08-31 01:33:06 +0000492 def test_format(self):
Eric Smith8c663262007-08-25 02:26:07 +0000493 # these should be rewritten to use both format(x, spec) and
494 # x.__format__(spec)
495
496 self.assertEqual(format(0.0, 'f'), '0.000000')
497
498 # the default is 'g', except for empty format spec
499 self.assertEqual(format(0.0, ''), '0.0')
500 self.assertEqual(format(0.01, ''), '0.01')
501 self.assertEqual(format(0.01, 'g'), '0.01')
502
Eric Smith63376222009-05-05 14:04:18 +0000503 # empty presentation type should format in the same way as str
504 # (issue 5920)
505 x = 100/7.
506 self.assertEqual(format(x, ''), str(x))
507 self.assertEqual(format(x, '-'), str(x))
508 self.assertEqual(format(x, '>'), str(x))
509 self.assertEqual(format(x, '2'), str(x))
Eric Smith8c663262007-08-25 02:26:07 +0000510
511 self.assertEqual(format(1.0, 'f'), '1.000000')
Eric Smith8c663262007-08-25 02:26:07 +0000512
513 self.assertEqual(format(-1.0, 'f'), '-1.000000')
Eric Smith8c663262007-08-25 02:26:07 +0000514
515 self.assertEqual(format( 1.0, ' f'), ' 1.000000')
516 self.assertEqual(format(-1.0, ' f'), '-1.000000')
517 self.assertEqual(format( 1.0, '+f'), '+1.000000')
518 self.assertEqual(format(-1.0, '+f'), '-1.000000')
519
520 # % formatting
521 self.assertEqual(format(-1.0, '%'), '-100.000000%')
522
523 # conversion to string should fail
524 self.assertRaises(ValueError, format, 3.0, "s")
525
Eric Smith7b69c6c2008-01-27 21:07:59 +0000526 # other format specifiers shouldn't work on floats,
527 # in particular int specifiers
528 for format_spec in ([chr(x) for x in range(ord('a'), ord('z')+1)] +
529 [chr(x) for x in range(ord('A'), ord('Z')+1)]):
530 if not format_spec in 'eEfFgGn%':
531 self.assertRaises(ValueError, format, 0.0, format_spec)
532 self.assertRaises(ValueError, format, 1.0, format_spec)
533 self.assertRaises(ValueError, format, -1.0, format_spec)
534 self.assertRaises(ValueError, format, 1e100, format_spec)
535 self.assertRaises(ValueError, format, -1e100, format_spec)
536 self.assertRaises(ValueError, format, 1e-100, format_spec)
537 self.assertRaises(ValueError, format, -1e-100, format_spec)
Michael W. Hudsonba283e22005-05-27 15:23:20 +0000538
Eric Smith741191f2009-05-06 13:08:15 +0000539 # issue 3382
540 self.assertEqual(format(NAN, 'f'), 'nan')
541 self.assertEqual(format(NAN, 'F'), 'NAN')
542 self.assertEqual(format(INF, 'f'), 'inf')
543 self.assertEqual(format(INF, 'F'), 'INF')
544
Eric Smith0923d1d2009-04-16 20:16:10 +0000545 @unittest.skipUnless(float.__getformat__("double").startswith("IEEE"),
546 "test requires IEEE 754 doubles")
547 def test_format_testfile(self):
548 for line in open(format_testfile):
549 if line.startswith('--'):
550 continue
551 line = line.strip()
552 if not line:
553 continue
554
555 lhs, rhs = map(str.strip, line.split('->'))
556 fmt, arg = lhs.split()
557 self.assertEqual(fmt % float(arg), rhs)
558 self.assertEqual(fmt % -float(arg), '-' + rhs)
559
Mark Dickinsond3ca5572009-04-29 18:47:07 +0000560 def test_issue5864(self):
561 self.assertEquals(format(123.456, '.4'), '123.5')
562 self.assertEquals(format(1234.56, '.4'), '1.235e+03')
563 self.assertEquals(format(12345.6, '.4'), '1.235e+04')
564
Mark Dickinson7efad9e2009-04-17 20:59:58 +0000565class ReprTestCase(unittest.TestCase):
566 def test_repr(self):
567 floats_file = open(os.path.join(os.path.split(__file__)[0],
568 'floating_points.txt'))
569 for line in floats_file:
570 line = line.strip()
571 if not line or line.startswith('#'):
572 continue
573 v = eval(line)
574 self.assertEqual(v, eval(repr(v)))
575 floats_file.close()
576
Eric Smith0923d1d2009-04-16 20:16:10 +0000577 @unittest.skipUnless(getattr(sys, 'float_repr_style', '') == 'short',
578 "applies only when using short float repr style")
579 def test_short_repr(self):
580 # test short float repr introduced in Python 3.1. One aspect
581 # of this repr is that we get some degree of str -> float ->
582 # str roundtripping. In particular, for any numeric string
583 # containing 15 or fewer significant digits, those exact same
584 # digits (modulo trailing zeros) should appear in the output.
585 # No more repr(0.03) -> "0.029999999999999999"!
586
587 test_strings = [
588 # output always includes *either* a decimal point and at
589 # least one digit after that point, or an exponent.
590 '0.0',
591 '1.0',
592 '0.01',
593 '0.02',
594 '0.03',
595 '0.04',
596 '0.05',
597 '1.23456789',
598 '10.0',
599 '100.0',
600 # values >= 1e16 get an exponent...
601 '1000000000000000.0',
602 '9999999999999990.0',
603 '1e+16',
604 '1e+17',
605 # ... and so do values < 1e-4
606 '0.001',
607 '0.001001',
608 '0.00010000000000001',
609 '0.0001',
610 '9.999999999999e-05',
611 '1e-05',
612 # values designed to provoke failure if the FPU rounding
613 # precision isn't set correctly
614 '8.72293771110361e+25',
615 '7.47005307342313e+26',
616 '2.86438000439698e+28',
617 '8.89142905246179e+28',
618 '3.08578087079232e+35',
619 ]
620
621 for s in test_strings:
622 negs = '-'+s
623 self.assertEqual(s, repr(float(s)))
624 self.assertEqual(negs, repr(float(negs)))
625
Mark Dickinsone6a076d2009-04-18 11:48:33 +0000626class RoundTestCase(unittest.TestCase):
627 @unittest.skipUnless(float.__getformat__("double").startswith("IEEE"),
628 "test requires IEEE 754 doubles")
629 def test_inf_nan(self):
630 self.assertRaises(OverflowError, round, INF)
631 self.assertRaises(OverflowError, round, -INF)
632 self.assertRaises(ValueError, round, NAN)
Mark Dickinson4ca33d12009-11-24 10:59:34 +0000633 self.assertRaises(TypeError, round, INF, 0.0)
634 self.assertRaises(TypeError, round, -INF, 1.0)
635 self.assertRaises(TypeError, round, NAN, "ceci n'est pas un integer")
636 self.assertRaises(TypeError, round, -0.0, 1j)
Mark Dickinsone6a076d2009-04-18 11:48:33 +0000637
638 @unittest.skipUnless(float.__getformat__("double").startswith("IEEE"),
639 "test requires IEEE 754 doubles")
640 def test_large_n(self):
641 for n in [324, 325, 400, 2**31-1, 2**31, 2**32, 2**100]:
642 self.assertEqual(round(123.456, n), 123.456)
643 self.assertEqual(round(-123.456, n), -123.456)
644 self.assertEqual(round(1e300, n), 1e300)
645 self.assertEqual(round(1e-320, n), 1e-320)
646 self.assertEqual(round(1e150, 300), 1e150)
647 self.assertEqual(round(1e300, 307), 1e300)
648 self.assertEqual(round(-3.1415, 308), -3.1415)
649 self.assertEqual(round(1e150, 309), 1e150)
650 self.assertEqual(round(1.4e-315, 315), 1e-315)
651
652 @unittest.skipUnless(float.__getformat__("double").startswith("IEEE"),
653 "test requires IEEE 754 doubles")
654 def test_small_n(self):
655 for n in [-308, -309, -400, 1-2**31, -2**31, -2**31-1, -2**100]:
656 self.assertEqual(round(123.456, n), 0.0)
657 self.assertEqual(round(-123.456, n), -0.0)
658 self.assertEqual(round(1e300, n), 0.0)
659 self.assertEqual(round(1e-320, n), 0.0)
660
661 @unittest.skipUnless(float.__getformat__("double").startswith("IEEE"),
662 "test requires IEEE 754 doubles")
663 def test_overflow(self):
664 self.assertRaises(OverflowError, round, 1.6e308, -308)
665 self.assertRaises(OverflowError, round, -1.7e308, -308)
666
667 @unittest.skipUnless(getattr(sys, 'float_repr_style', '') == 'short',
668 "applies only when using short float repr style")
669 def test_previous_round_bugs(self):
670 # particular cases that have occurred in bug reports
671 self.assertEqual(round(562949953421312.5, 1),
672 562949953421312.5)
673 self.assertEqual(round(56294995342131.5, 3),
674 56294995342131.5)
675 # round-half-even
676 self.assertEqual(round(25.0, -1), 20.0)
677 self.assertEqual(round(35.0, -1), 40.0)
678 self.assertEqual(round(45.0, -1), 40.0)
679 self.assertEqual(round(55.0, -1), 60.0)
680 self.assertEqual(round(65.0, -1), 60.0)
681 self.assertEqual(round(75.0, -1), 80.0)
682 self.assertEqual(round(85.0, -1), 80.0)
683 self.assertEqual(round(95.0, -1), 100.0)
684
685 @unittest.skipUnless(getattr(sys, 'float_repr_style', '') == 'short',
686 "applies only when using short float repr style")
687 def test_matches_float_format(self):
688 # round should give the same results as float formatting
689 for i in range(500):
690 x = i/1000.
691 self.assertEqual(float(format(x, '.0f')), round(x, 0))
692 self.assertEqual(float(format(x, '.1f')), round(x, 1))
693 self.assertEqual(float(format(x, '.2f')), round(x, 2))
694 self.assertEqual(float(format(x, '.3f')), round(x, 3))
695
696 for i in range(5, 5000, 10):
697 x = i/1000.
698 self.assertEqual(float(format(x, '.0f')), round(x, 0))
699 self.assertEqual(float(format(x, '.1f')), round(x, 1))
700 self.assertEqual(float(format(x, '.2f')), round(x, 2))
701 self.assertEqual(float(format(x, '.3f')), round(x, 3))
702
703 for i in range(500):
704 x = random.random()
705 self.assertEqual(float(format(x, '.0f')), round(x, 0))
706 self.assertEqual(float(format(x, '.1f')), round(x, 1))
707 self.assertEqual(float(format(x, '.2f')), round(x, 2))
708 self.assertEqual(float(format(x, '.3f')), round(x, 3))
709
710
Eric Smith8a10ecc2009-12-02 17:58:24 +0000711 @unittest.skipUnless(float.__getformat__("double").startswith("IEEE"),
712 "test requires IEEE 754 doubles")
713 def test_format_specials(self):
714 # Test formatting of nans and infs.
715
716 def test(fmt, value, expected):
717 # Test with both % and format().
718 self.assertEqual(fmt % value, expected, fmt)
719 if not '#' in fmt:
720 # Until issue 7094 is implemented, format() for floats doesn't
721 # support '#' formatting
722 fmt = fmt[1:] # strip off the %
723 self.assertEqual(format(value, fmt), expected, fmt)
724
725 for fmt in ['%e', '%f', '%g', '%.0e', '%.6f', '%.20g',
726 '%#e', '%#f', '%#g', '%#.20e', '%#.15f', '%#.3g']:
727 pfmt = '%+' + fmt[1:]
728 sfmt = '% ' + fmt[1:]
729 test(fmt, INF, 'inf')
730 test(fmt, -INF, '-inf')
731 test(fmt, NAN, 'nan')
732 test(fmt, -NAN, 'nan')
733 # When asking for a sign, it's always provided. nans are
734 # always positive.
735 test(pfmt, INF, '+inf')
736 test(pfmt, -INF, '-inf')
737 test(pfmt, NAN, '+nan')
738 test(pfmt, -NAN, '+nan')
739 # When using ' ' for a sign code, only infs can be negative.
740 # Others have a space.
741 test(sfmt, INF, ' inf')
742 test(sfmt, -INF, '-inf')
743 test(sfmt, NAN, ' nan')
744 test(sfmt, -NAN, ' nan')
745
Mark Dickinsone6a076d2009-04-18 11:48:33 +0000746
Christian Heimes99170a52007-12-19 02:07:34 +0000747# Beginning with Python 2.6 float has cross platform compatible
Georg Brandl2ee470f2008-07-16 12:55:28 +0000748# ways to create and represent inf and nan
Christian Heimes99170a52007-12-19 02:07:34 +0000749class InfNanTest(unittest.TestCase):
750 def test_inf_from_str(self):
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000751 self.assertTrue(isinf(float("inf")))
752 self.assertTrue(isinf(float("+inf")))
753 self.assertTrue(isinf(float("-inf")))
754 self.assertTrue(isinf(float("infinity")))
755 self.assertTrue(isinf(float("+infinity")))
756 self.assertTrue(isinf(float("-infinity")))
Christian Heimes99170a52007-12-19 02:07:34 +0000757
758 self.assertEqual(repr(float("inf")), "inf")
759 self.assertEqual(repr(float("+inf")), "inf")
760 self.assertEqual(repr(float("-inf")), "-inf")
Georg Brandl2ee470f2008-07-16 12:55:28 +0000761 self.assertEqual(repr(float("infinity")), "inf")
762 self.assertEqual(repr(float("+infinity")), "inf")
763 self.assertEqual(repr(float("-infinity")), "-inf")
Christian Heimes99170a52007-12-19 02:07:34 +0000764
765 self.assertEqual(repr(float("INF")), "inf")
766 self.assertEqual(repr(float("+Inf")), "inf")
767 self.assertEqual(repr(float("-iNF")), "-inf")
Georg Brandl2ee470f2008-07-16 12:55:28 +0000768 self.assertEqual(repr(float("Infinity")), "inf")
769 self.assertEqual(repr(float("+iNfInItY")), "inf")
770 self.assertEqual(repr(float("-INFINITY")), "-inf")
Christian Heimes99170a52007-12-19 02:07:34 +0000771
772 self.assertEqual(str(float("inf")), "inf")
773 self.assertEqual(str(float("+inf")), "inf")
774 self.assertEqual(str(float("-inf")), "-inf")
Georg Brandl2ee470f2008-07-16 12:55:28 +0000775 self.assertEqual(str(float("infinity")), "inf")
776 self.assertEqual(str(float("+infinity")), "inf")
777 self.assertEqual(str(float("-infinity")), "-inf")
Christian Heimes99170a52007-12-19 02:07:34 +0000778
779 self.assertRaises(ValueError, float, "info")
780 self.assertRaises(ValueError, float, "+info")
781 self.assertRaises(ValueError, float, "-info")
782 self.assertRaises(ValueError, float, "in")
783 self.assertRaises(ValueError, float, "+in")
784 self.assertRaises(ValueError, float, "-in")
Georg Brandl2ee470f2008-07-16 12:55:28 +0000785 self.assertRaises(ValueError, float, "infinit")
786 self.assertRaises(ValueError, float, "+Infin")
787 self.assertRaises(ValueError, float, "-INFI")
788 self.assertRaises(ValueError, float, "infinitys")
Christian Heimes99170a52007-12-19 02:07:34 +0000789
Mark Dickinsonbd16edd2009-05-20 22:05:25 +0000790 self.assertRaises(ValueError, float, "++Inf")
791 self.assertRaises(ValueError, float, "-+inf")
792 self.assertRaises(ValueError, float, "+-infinity")
793 self.assertRaises(ValueError, float, "--Infinity")
794
Christian Heimes99170a52007-12-19 02:07:34 +0000795 def test_inf_as_str(self):
796 self.assertEqual(repr(1e300 * 1e300), "inf")
797 self.assertEqual(repr(-1e300 * 1e300), "-inf")
798
799 self.assertEqual(str(1e300 * 1e300), "inf")
800 self.assertEqual(str(-1e300 * 1e300), "-inf")
801
802 def test_nan_from_str(self):
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000803 self.assertTrue(isnan(float("nan")))
804 self.assertTrue(isnan(float("+nan")))
805 self.assertTrue(isnan(float("-nan")))
Christian Heimes99170a52007-12-19 02:07:34 +0000806
807 self.assertEqual(repr(float("nan")), "nan")
808 self.assertEqual(repr(float("+nan")), "nan")
809 self.assertEqual(repr(float("-nan")), "nan")
810
811 self.assertEqual(repr(float("NAN")), "nan")
812 self.assertEqual(repr(float("+NAn")), "nan")
813 self.assertEqual(repr(float("-NaN")), "nan")
814
815 self.assertEqual(str(float("nan")), "nan")
816 self.assertEqual(str(float("+nan")), "nan")
817 self.assertEqual(str(float("-nan")), "nan")
818
819 self.assertRaises(ValueError, float, "nana")
820 self.assertRaises(ValueError, float, "+nana")
821 self.assertRaises(ValueError, float, "-nana")
822 self.assertRaises(ValueError, float, "na")
823 self.assertRaises(ValueError, float, "+na")
824 self.assertRaises(ValueError, float, "-na")
825
Mark Dickinsonbd16edd2009-05-20 22:05:25 +0000826 self.assertRaises(ValueError, float, "++nan")
827 self.assertRaises(ValueError, float, "-+NAN")
828 self.assertRaises(ValueError, float, "+-NaN")
829 self.assertRaises(ValueError, float, "--nAn")
830
Christian Heimes99170a52007-12-19 02:07:34 +0000831 def test_nan_as_str(self):
832 self.assertEqual(repr(1e300 * 1e300 * 0), "nan")
833 self.assertEqual(repr(-1e300 * 1e300 * 0), "nan")
834
835 self.assertEqual(str(1e300 * 1e300 * 0), "nan")
836 self.assertEqual(str(-1e300 * 1e300 * 0), "nan")
Christian Heimes827b35c2007-12-10 22:19:17 +0000837
Christian Heimes53876d92008-04-19 00:31:39 +0000838 def notest_float_nan(self):
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000839 self.assertTrue(NAN.is_nan())
840 self.assertFalse(INF.is_nan())
841 self.assertFalse((0.).is_nan())
Christian Heimes53876d92008-04-19 00:31:39 +0000842
843 def notest_float_inf(self):
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000844 self.assertTrue(INF.is_inf())
845 self.assertFalse(NAN.is_inf())
846 self.assertFalse((0.).is_inf())
Christian Heimes53876d92008-04-19 00:31:39 +0000847
Mark Dickinson65fe25e2008-07-16 11:30:51 +0000848fromHex = float.fromhex
849toHex = float.hex
850class HexFloatTestCase(unittest.TestCase):
851 MAX = fromHex('0x.fffffffffffff8p+1024') # max normal
852 MIN = fromHex('0x1p-1022') # min normal
853 TINY = fromHex('0x0.0000000000001p-1022') # min subnormal
854 EPS = fromHex('0x0.0000000000001p0') # diff between 1.0 and next float up
855
856 def identical(self, x, y):
857 # check that floats x and y are identical, or that both
858 # are NaNs
859 if isnan(x) or isnan(y):
860 if isnan(x) == isnan(y):
861 return
862 elif x == y and (x != 0.0 or copysign(1.0, x) == copysign(1.0, y)):
863 return
864 self.fail('%r not identical to %r' % (x, y))
865
866 def test_ends(self):
Mark Dickinson38bbc482008-07-16 11:32:23 +0000867 self.identical(self.MIN, ldexp(1.0, -1022))
868 self.identical(self.TINY, ldexp(1.0, -1074))
869 self.identical(self.EPS, ldexp(1.0, -52))
870 self.identical(self.MAX, 2.*(ldexp(1.0, 1023) - ldexp(1.0, 970)))
Mark Dickinson65fe25e2008-07-16 11:30:51 +0000871
872 def test_invalid_inputs(self):
873 invalid_inputs = [
874 'infi', # misspelt infinities and nans
875 '-Infinit',
876 '++inf',
877 '-+Inf',
878 '--nan',
879 '+-NaN',
880 'snan',
881 'NaNs',
882 'nna',
Mark Dickinsond1ec8b22009-05-11 15:45:15 +0000883 'an',
884 'nf',
885 'nfinity',
886 'inity',
887 'iinity',
Mark Dickinson65fe25e2008-07-16 11:30:51 +0000888 '0xnan',
889 '',
890 ' ',
891 'x1.0p0',
892 '0xX1.0p0',
893 '+ 0x1.0p0', # internal whitespace
894 '- 0x1.0p0',
895 '0 x1.0p0',
896 '0x 1.0p0',
897 '0x1 2.0p0',
898 '+0x1 .0p0',
899 '0x1. 0p0',
900 '-0x1.0 1p0',
901 '-0x1.0 p0',
902 '+0x1.0p +0',
903 '0x1.0p -0',
904 '0x1.0p 0',
905 '+0x1.0p+ 0',
906 '-0x1.0p- 0',
907 '++0x1.0p-0', # double signs
908 '--0x1.0p0',
909 '+-0x1.0p+0',
910 '-+0x1.0p0',
911 '0x1.0p++0',
912 '+0x1.0p+-0',
913 '-0x1.0p-+0',
914 '0x1.0p--0',
915 '0x1.0.p0',
916 '0x.p0', # no hex digits before or after point
917 '0x1,p0', # wrong decimal point character
918 '0x1pa',
919 '0x1p\uff10', # fullwidth Unicode digits
920 '\uff10x1p0',
921 '0x\uff11p0',
922 '0x1.\uff10p0',
923 '0x1p0 \n 0x2p0',
924 '0x1p0\0 0x1p0', # embedded null byte is not end of string
925 ]
926 for x in invalid_inputs:
Mark Dickinson589b7952008-08-21 20:05:56 +0000927 try:
928 result = fromHex(x)
929 except ValueError:
930 pass
931 else:
932 self.fail('Expected float.fromhex(%r) to raise ValueError; '
933 'got %r instead' % (x, result))
Mark Dickinson65fe25e2008-07-16 11:30:51 +0000934
935
Mark Dickinsond1ec8b22009-05-11 15:45:15 +0000936 def test_whitespace(self):
937 value_pairs = [
938 ('inf', INF),
939 ('-Infinity', -INF),
940 ('nan', NAN),
941 ('1.0', 1.0),
942 ('-0x.2', -0.125),
943 ('-0.0', -0.0)
944 ]
945 whitespace = [
946 '',
947 ' ',
948 '\t',
949 '\n',
950 '\n \t',
951 '\f',
952 '\v',
953 '\r'
954 ]
955 for inp, expected in value_pairs:
956 for lead in whitespace:
957 for trail in whitespace:
958 got = fromHex(lead + inp + trail)
959 self.identical(got, expected)
960
961
Mark Dickinson65fe25e2008-07-16 11:30:51 +0000962 def test_from_hex(self):
963 MIN = self.MIN;
964 MAX = self.MAX;
965 TINY = self.TINY;
966 EPS = self.EPS;
967
968 # two spellings of infinity, with optional signs; case-insensitive
969 self.identical(fromHex('inf'), INF)
970 self.identical(fromHex('+Inf'), INF)
971 self.identical(fromHex('-INF'), -INF)
972 self.identical(fromHex('iNf'), INF)
973 self.identical(fromHex('Infinity'), INF)
974 self.identical(fromHex('+INFINITY'), INF)
975 self.identical(fromHex('-infinity'), -INF)
976 self.identical(fromHex('-iNFiNitY'), -INF)
977
978 # nans with optional sign; case insensitive
979 self.identical(fromHex('nan'), NAN)
980 self.identical(fromHex('+NaN'), NAN)
981 self.identical(fromHex('-NaN'), NAN)
982 self.identical(fromHex('-nAN'), NAN)
983
984 # variations in input format
985 self.identical(fromHex('1'), 1.0)
986 self.identical(fromHex('+1'), 1.0)
987 self.identical(fromHex('1.'), 1.0)
988 self.identical(fromHex('1.0'), 1.0)
989 self.identical(fromHex('1.0p0'), 1.0)
990 self.identical(fromHex('01'), 1.0)
991 self.identical(fromHex('01.'), 1.0)
992 self.identical(fromHex('0x1'), 1.0)
993 self.identical(fromHex('0x1.'), 1.0)
994 self.identical(fromHex('0x1.0'), 1.0)
995 self.identical(fromHex('+0x1.0'), 1.0)
996 self.identical(fromHex('0x1p0'), 1.0)
997 self.identical(fromHex('0X1p0'), 1.0)
998 self.identical(fromHex('0X1P0'), 1.0)
999 self.identical(fromHex('0x1P0'), 1.0)
1000 self.identical(fromHex('0x1.p0'), 1.0)
1001 self.identical(fromHex('0x1.0p0'), 1.0)
1002 self.identical(fromHex('0x.1p4'), 1.0)
1003 self.identical(fromHex('0x.1p04'), 1.0)
1004 self.identical(fromHex('0x.1p004'), 1.0)
1005 self.identical(fromHex('0x1p+0'), 1.0)
1006 self.identical(fromHex('0x1P-0'), 1.0)
1007 self.identical(fromHex('+0x1p0'), 1.0)
1008 self.identical(fromHex('0x01p0'), 1.0)
1009 self.identical(fromHex('0x1p00'), 1.0)
1010 self.identical(fromHex(' 0x1p0 '), 1.0)
1011 self.identical(fromHex('\n 0x1p0'), 1.0)
1012 self.identical(fromHex('0x1p0 \t'), 1.0)
1013 self.identical(fromHex('0xap0'), 10.0)
1014 self.identical(fromHex('0xAp0'), 10.0)
1015 self.identical(fromHex('0xaP0'), 10.0)
1016 self.identical(fromHex('0xAP0'), 10.0)
1017 self.identical(fromHex('0xbep0'), 190.0)
1018 self.identical(fromHex('0xBep0'), 190.0)
1019 self.identical(fromHex('0xbEp0'), 190.0)
1020 self.identical(fromHex('0XBE0P-4'), 190.0)
1021 self.identical(fromHex('0xBEp0'), 190.0)
1022 self.identical(fromHex('0xB.Ep4'), 190.0)
1023 self.identical(fromHex('0x.BEp8'), 190.0)
1024 self.identical(fromHex('0x.0BEp12'), 190.0)
1025
1026 # moving the point around
1027 pi = fromHex('0x1.921fb54442d18p1')
1028 self.identical(fromHex('0x.006487ed5110b46p11'), pi)
1029 self.identical(fromHex('0x.00c90fdaa22168cp10'), pi)
1030 self.identical(fromHex('0x.01921fb54442d18p9'), pi)
1031 self.identical(fromHex('0x.03243f6a8885a3p8'), pi)
1032 self.identical(fromHex('0x.06487ed5110b46p7'), pi)
1033 self.identical(fromHex('0x.0c90fdaa22168cp6'), pi)
1034 self.identical(fromHex('0x.1921fb54442d18p5'), pi)
1035 self.identical(fromHex('0x.3243f6a8885a3p4'), pi)
1036 self.identical(fromHex('0x.6487ed5110b46p3'), pi)
1037 self.identical(fromHex('0x.c90fdaa22168cp2'), pi)
1038 self.identical(fromHex('0x1.921fb54442d18p1'), pi)
1039 self.identical(fromHex('0x3.243f6a8885a3p0'), pi)
1040 self.identical(fromHex('0x6.487ed5110b46p-1'), pi)
1041 self.identical(fromHex('0xc.90fdaa22168cp-2'), pi)
1042 self.identical(fromHex('0x19.21fb54442d18p-3'), pi)
1043 self.identical(fromHex('0x32.43f6a8885a3p-4'), pi)
1044 self.identical(fromHex('0x64.87ed5110b46p-5'), pi)
1045 self.identical(fromHex('0xc9.0fdaa22168cp-6'), pi)
1046 self.identical(fromHex('0x192.1fb54442d18p-7'), pi)
1047 self.identical(fromHex('0x324.3f6a8885a3p-8'), pi)
1048 self.identical(fromHex('0x648.7ed5110b46p-9'), pi)
1049 self.identical(fromHex('0xc90.fdaa22168cp-10'), pi)
1050 self.identical(fromHex('0x1921.fb54442d18p-11'), pi)
1051 # ...
1052 self.identical(fromHex('0x1921fb54442d1.8p-47'), pi)
1053 self.identical(fromHex('0x3243f6a8885a3p-48'), pi)
1054 self.identical(fromHex('0x6487ed5110b46p-49'), pi)
1055 self.identical(fromHex('0xc90fdaa22168cp-50'), pi)
1056 self.identical(fromHex('0x1921fb54442d18p-51'), pi)
1057 self.identical(fromHex('0x3243f6a8885a30p-52'), pi)
1058 self.identical(fromHex('0x6487ed5110b460p-53'), pi)
1059 self.identical(fromHex('0xc90fdaa22168c0p-54'), pi)
1060 self.identical(fromHex('0x1921fb54442d180p-55'), pi)
1061
1062
1063 # results that should overflow...
1064 self.assertRaises(OverflowError, fromHex, '-0x1p1024')
1065 self.assertRaises(OverflowError, fromHex, '0x1p+1025')
1066 self.assertRaises(OverflowError, fromHex, '+0X1p1030')
1067 self.assertRaises(OverflowError, fromHex, '-0x1p+1100')
1068 self.assertRaises(OverflowError, fromHex, '0X1p123456789123456789')
1069 self.assertRaises(OverflowError, fromHex, '+0X.8p+1025')
1070 self.assertRaises(OverflowError, fromHex, '+0x0.8p1025')
1071 self.assertRaises(OverflowError, fromHex, '-0x0.4p1026')
1072 self.assertRaises(OverflowError, fromHex, '0X2p+1023')
1073 self.assertRaises(OverflowError, fromHex, '0x2.p1023')
1074 self.assertRaises(OverflowError, fromHex, '-0x2.0p+1023')
1075 self.assertRaises(OverflowError, fromHex, '+0X4p+1022')
1076 self.assertRaises(OverflowError, fromHex, '0x1.ffffffffffffffp+1023')
1077 self.assertRaises(OverflowError, fromHex, '-0X1.fffffffffffff9p1023')
1078 self.assertRaises(OverflowError, fromHex, '0X1.fffffffffffff8p1023')
1079 self.assertRaises(OverflowError, fromHex, '+0x3.fffffffffffffp1022')
1080 self.assertRaises(OverflowError, fromHex, '0x3fffffffffffffp+970')
1081 self.assertRaises(OverflowError, fromHex, '0x10000000000000000p960')
1082 self.assertRaises(OverflowError, fromHex, '-0Xffffffffffffffffp960')
1083
1084 # ...and those that round to +-max float
1085 self.identical(fromHex('+0x1.fffffffffffffp+1023'), MAX)
1086 self.identical(fromHex('-0X1.fffffffffffff7p1023'), -MAX)
1087 self.identical(fromHex('0X1.fffffffffffff7fffffffffffffp1023'), MAX)
1088
1089 # zeros
1090 self.identical(fromHex('0x0p0'), 0.0)
1091 self.identical(fromHex('0x0p1000'), 0.0)
1092 self.identical(fromHex('-0x0p1023'), -0.0)
1093 self.identical(fromHex('0X0p1024'), 0.0)
1094 self.identical(fromHex('-0x0p1025'), -0.0)
1095 self.identical(fromHex('0X0p2000'), 0.0)
1096 self.identical(fromHex('0x0p123456789123456789'), 0.0)
1097 self.identical(fromHex('-0X0p-0'), -0.0)
1098 self.identical(fromHex('-0X0p-1000'), -0.0)
1099 self.identical(fromHex('0x0p-1023'), 0.0)
1100 self.identical(fromHex('-0X0p-1024'), -0.0)
1101 self.identical(fromHex('-0x0p-1025'), -0.0)
1102 self.identical(fromHex('-0x0p-1072'), -0.0)
1103 self.identical(fromHex('0X0p-1073'), 0.0)
1104 self.identical(fromHex('-0x0p-1074'), -0.0)
1105 self.identical(fromHex('0x0p-1075'), 0.0)
1106 self.identical(fromHex('0X0p-1076'), 0.0)
1107 self.identical(fromHex('-0X0p-2000'), -0.0)
1108 self.identical(fromHex('-0x0p-123456789123456789'), -0.0)
1109
1110 # values that should underflow to 0
1111 self.identical(fromHex('0X1p-1075'), 0.0)
1112 self.identical(fromHex('-0X1p-1075'), -0.0)
1113 self.identical(fromHex('-0x1p-123456789123456789'), -0.0)
1114 self.identical(fromHex('0x1.00000000000000001p-1075'), TINY)
1115 self.identical(fromHex('-0x1.1p-1075'), -TINY)
1116 self.identical(fromHex('0x1.fffffffffffffffffp-1075'), TINY)
1117
1118 # check round-half-even is working correctly near 0 ...
1119 self.identical(fromHex('0x1p-1076'), 0.0)
1120 self.identical(fromHex('0X2p-1076'), 0.0)
1121 self.identical(fromHex('0X3p-1076'), TINY)
1122 self.identical(fromHex('0x4p-1076'), TINY)
1123 self.identical(fromHex('0X5p-1076'), TINY)
1124 self.identical(fromHex('0X6p-1076'), 2*TINY)
1125 self.identical(fromHex('0x7p-1076'), 2*TINY)
1126 self.identical(fromHex('0X8p-1076'), 2*TINY)
1127 self.identical(fromHex('0X9p-1076'), 2*TINY)
1128 self.identical(fromHex('0xap-1076'), 2*TINY)
1129 self.identical(fromHex('0Xbp-1076'), 3*TINY)
1130 self.identical(fromHex('0xcp-1076'), 3*TINY)
1131 self.identical(fromHex('0Xdp-1076'), 3*TINY)
1132 self.identical(fromHex('0Xep-1076'), 4*TINY)
1133 self.identical(fromHex('0xfp-1076'), 4*TINY)
1134 self.identical(fromHex('0x10p-1076'), 4*TINY)
1135 self.identical(fromHex('-0x1p-1076'), -0.0)
1136 self.identical(fromHex('-0X2p-1076'), -0.0)
1137 self.identical(fromHex('-0x3p-1076'), -TINY)
1138 self.identical(fromHex('-0X4p-1076'), -TINY)
1139 self.identical(fromHex('-0x5p-1076'), -TINY)
1140 self.identical(fromHex('-0x6p-1076'), -2*TINY)
1141 self.identical(fromHex('-0X7p-1076'), -2*TINY)
1142 self.identical(fromHex('-0X8p-1076'), -2*TINY)
1143 self.identical(fromHex('-0X9p-1076'), -2*TINY)
1144 self.identical(fromHex('-0Xap-1076'), -2*TINY)
1145 self.identical(fromHex('-0xbp-1076'), -3*TINY)
1146 self.identical(fromHex('-0xcp-1076'), -3*TINY)
1147 self.identical(fromHex('-0Xdp-1076'), -3*TINY)
1148 self.identical(fromHex('-0xep-1076'), -4*TINY)
1149 self.identical(fromHex('-0Xfp-1076'), -4*TINY)
1150 self.identical(fromHex('-0X10p-1076'), -4*TINY)
1151
1152 # ... and near MIN ...
1153 self.identical(fromHex('0x0.ffffffffffffd6p-1022'), MIN-3*TINY)
1154 self.identical(fromHex('0x0.ffffffffffffd8p-1022'), MIN-2*TINY)
1155 self.identical(fromHex('0x0.ffffffffffffdap-1022'), MIN-2*TINY)
1156 self.identical(fromHex('0x0.ffffffffffffdcp-1022'), MIN-2*TINY)
1157 self.identical(fromHex('0x0.ffffffffffffdep-1022'), MIN-2*TINY)
1158 self.identical(fromHex('0x0.ffffffffffffe0p-1022'), MIN-2*TINY)
1159 self.identical(fromHex('0x0.ffffffffffffe2p-1022'), MIN-2*TINY)
1160 self.identical(fromHex('0x0.ffffffffffffe4p-1022'), MIN-2*TINY)
1161 self.identical(fromHex('0x0.ffffffffffffe6p-1022'), MIN-2*TINY)
1162 self.identical(fromHex('0x0.ffffffffffffe8p-1022'), MIN-2*TINY)
1163 self.identical(fromHex('0x0.ffffffffffffeap-1022'), MIN-TINY)
1164 self.identical(fromHex('0x0.ffffffffffffecp-1022'), MIN-TINY)
1165 self.identical(fromHex('0x0.ffffffffffffeep-1022'), MIN-TINY)
1166 self.identical(fromHex('0x0.fffffffffffff0p-1022'), MIN-TINY)
1167 self.identical(fromHex('0x0.fffffffffffff2p-1022'), MIN-TINY)
1168 self.identical(fromHex('0x0.fffffffffffff4p-1022'), MIN-TINY)
1169 self.identical(fromHex('0x0.fffffffffffff6p-1022'), MIN-TINY)
1170 self.identical(fromHex('0x0.fffffffffffff8p-1022'), MIN)
1171 self.identical(fromHex('0x0.fffffffffffffap-1022'), MIN)
1172 self.identical(fromHex('0x0.fffffffffffffcp-1022'), MIN)
1173 self.identical(fromHex('0x0.fffffffffffffep-1022'), MIN)
1174 self.identical(fromHex('0x1.00000000000000p-1022'), MIN)
1175 self.identical(fromHex('0x1.00000000000002p-1022'), MIN)
1176 self.identical(fromHex('0x1.00000000000004p-1022'), MIN)
1177 self.identical(fromHex('0x1.00000000000006p-1022'), MIN)
1178 self.identical(fromHex('0x1.00000000000008p-1022'), MIN)
1179 self.identical(fromHex('0x1.0000000000000ap-1022'), MIN+TINY)
1180 self.identical(fromHex('0x1.0000000000000cp-1022'), MIN+TINY)
1181 self.identical(fromHex('0x1.0000000000000ep-1022'), MIN+TINY)
1182 self.identical(fromHex('0x1.00000000000010p-1022'), MIN+TINY)
1183 self.identical(fromHex('0x1.00000000000012p-1022'), MIN+TINY)
1184 self.identical(fromHex('0x1.00000000000014p-1022'), MIN+TINY)
1185 self.identical(fromHex('0x1.00000000000016p-1022'), MIN+TINY)
1186 self.identical(fromHex('0x1.00000000000018p-1022'), MIN+2*TINY)
1187
1188 # ... and near 1.0.
1189 self.identical(fromHex('0x0.fffffffffffff0p0'), 1.0-EPS)
1190 self.identical(fromHex('0x0.fffffffffffff1p0'), 1.0-EPS)
1191 self.identical(fromHex('0X0.fffffffffffff2p0'), 1.0-EPS)
1192 self.identical(fromHex('0x0.fffffffffffff3p0'), 1.0-EPS)
1193 self.identical(fromHex('0X0.fffffffffffff4p0'), 1.0-EPS)
1194 self.identical(fromHex('0X0.fffffffffffff5p0'), 1.0-EPS/2)
1195 self.identical(fromHex('0X0.fffffffffffff6p0'), 1.0-EPS/2)
1196 self.identical(fromHex('0x0.fffffffffffff7p0'), 1.0-EPS/2)
1197 self.identical(fromHex('0x0.fffffffffffff8p0'), 1.0-EPS/2)
1198 self.identical(fromHex('0X0.fffffffffffff9p0'), 1.0-EPS/2)
1199 self.identical(fromHex('0X0.fffffffffffffap0'), 1.0-EPS/2)
1200 self.identical(fromHex('0x0.fffffffffffffbp0'), 1.0-EPS/2)
1201 self.identical(fromHex('0X0.fffffffffffffcp0'), 1.0)
1202 self.identical(fromHex('0x0.fffffffffffffdp0'), 1.0)
1203 self.identical(fromHex('0X0.fffffffffffffep0'), 1.0)
1204 self.identical(fromHex('0x0.ffffffffffffffp0'), 1.0)
1205 self.identical(fromHex('0X1.00000000000000p0'), 1.0)
1206 self.identical(fromHex('0X1.00000000000001p0'), 1.0)
1207 self.identical(fromHex('0x1.00000000000002p0'), 1.0)
1208 self.identical(fromHex('0X1.00000000000003p0'), 1.0)
1209 self.identical(fromHex('0x1.00000000000004p0'), 1.0)
1210 self.identical(fromHex('0X1.00000000000005p0'), 1.0)
1211 self.identical(fromHex('0X1.00000000000006p0'), 1.0)
1212 self.identical(fromHex('0X1.00000000000007p0'), 1.0)
1213 self.identical(fromHex('0x1.00000000000007ffffffffffffffffffffp0'),
1214 1.0)
1215 self.identical(fromHex('0x1.00000000000008p0'), 1.0)
1216 self.identical(fromHex('0x1.00000000000008000000000000000001p0'),
1217 1+EPS)
1218 self.identical(fromHex('0X1.00000000000009p0'), 1.0+EPS)
1219 self.identical(fromHex('0x1.0000000000000ap0'), 1.0+EPS)
1220 self.identical(fromHex('0x1.0000000000000bp0'), 1.0+EPS)
1221 self.identical(fromHex('0X1.0000000000000cp0'), 1.0+EPS)
1222 self.identical(fromHex('0x1.0000000000000dp0'), 1.0+EPS)
1223 self.identical(fromHex('0x1.0000000000000ep0'), 1.0+EPS)
1224 self.identical(fromHex('0X1.0000000000000fp0'), 1.0+EPS)
1225 self.identical(fromHex('0x1.00000000000010p0'), 1.0+EPS)
1226 self.identical(fromHex('0X1.00000000000011p0'), 1.0+EPS)
1227 self.identical(fromHex('0x1.00000000000012p0'), 1.0+EPS)
1228 self.identical(fromHex('0X1.00000000000013p0'), 1.0+EPS)
1229 self.identical(fromHex('0X1.00000000000014p0'), 1.0+EPS)
1230 self.identical(fromHex('0x1.00000000000015p0'), 1.0+EPS)
1231 self.identical(fromHex('0x1.00000000000016p0'), 1.0+EPS)
1232 self.identical(fromHex('0X1.00000000000017p0'), 1.0+EPS)
1233 self.identical(fromHex('0x1.00000000000017ffffffffffffffffffffp0'),
1234 1.0+EPS)
1235 self.identical(fromHex('0x1.00000000000018p0'), 1.0+2*EPS)
1236 self.identical(fromHex('0X1.00000000000018000000000000000001p0'),
1237 1.0+2*EPS)
1238 self.identical(fromHex('0x1.00000000000019p0'), 1.0+2*EPS)
1239 self.identical(fromHex('0X1.0000000000001ap0'), 1.0+2*EPS)
1240 self.identical(fromHex('0X1.0000000000001bp0'), 1.0+2*EPS)
1241 self.identical(fromHex('0x1.0000000000001cp0'), 1.0+2*EPS)
1242 self.identical(fromHex('0x1.0000000000001dp0'), 1.0+2*EPS)
1243 self.identical(fromHex('0x1.0000000000001ep0'), 1.0+2*EPS)
1244 self.identical(fromHex('0X1.0000000000001fp0'), 1.0+2*EPS)
1245 self.identical(fromHex('0x1.00000000000020p0'), 1.0+2*EPS)
1246
1247 def test_roundtrip(self):
1248 def roundtrip(x):
1249 return fromHex(toHex(x))
1250
1251 for x in [NAN, INF, self.MAX, self.MIN, self.MIN-self.TINY, self.TINY, 0.0]:
1252 self.identical(x, roundtrip(x))
1253 self.identical(-x, roundtrip(-x))
1254
1255 # fromHex(toHex(x)) should exactly recover x, for any non-NaN float x.
1256 import random
1257 for i in range(10000):
1258 e = random.randrange(-1200, 1200)
1259 m = random.random()
1260 s = random.choice([1.0, -1.0])
1261 try:
1262 x = s*ldexp(m, e)
1263 except OverflowError:
1264 pass
1265 else:
1266 self.identical(x, fromHex(toHex(x)))
1267
Christian Heimes53876d92008-04-19 00:31:39 +00001268
Michael W. Hudsonba283e22005-05-27 15:23:20 +00001269def test_main():
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001270 support.run_unittest(
Amaury Forgeot d'Arc7e958d12008-09-06 21:03:22 +00001271 GeneralFloatCases,
Michael W. Hudsonba283e22005-05-27 15:23:20 +00001272 FormatFunctionsTestCase,
1273 UnknownFormatTestCase,
Eric Smith8c663262007-08-25 02:26:07 +00001274 IEEEFormatTestCase,
Christian Heimes827b35c2007-12-10 22:19:17 +00001275 FormatTestCase,
Christian Heimes99170a52007-12-19 02:07:34 +00001276 ReprTestCase,
Mark Dickinsone6a076d2009-04-18 11:48:33 +00001277 RoundTestCase,
Christian Heimes99170a52007-12-19 02:07:34 +00001278 InfNanTest,
Mark Dickinson65fe25e2008-07-16 11:30:51 +00001279 HexFloatTestCase,
Christian Heimesb76922a2007-12-11 01:06:40 +00001280 )
Michael W. Hudsonba283e22005-05-27 15:23:20 +00001281
1282if __name__ == '__main__':
1283 test_main()