blob: 504f39c4eedd786ba87e75da40cd43a30d5f7da4 [file] [log] [blame]
Michael W. Hudsonba283e22005-05-27 15:23:20 +00001
Benjamin Peterson101447b2015-03-09 10:37:50 -04002import fractions
Christian Heimes53876d92008-04-19 00:31:39 +00003import math
Christian Heimes53876d92008-04-19 00:31:39 +00004import operator
Benjamin Peterson101447b2015-03-09 10:37:50 -04005import os
6import random
7import sys
8import struct
Benjamin Petersona9157232015-03-06 09:08:44 -05009import time
Benjamin Peterson101447b2015-03-09 10:37:50 -040010import unittest
11
12from test import support
13from math import isinf, isnan, copysign, ldexp
Michael W. Hudsonba283e22005-05-27 15:23:20 +000014
Christian Heimes53876d92008-04-19 00:31:39 +000015INF = float("inf")
16NAN = float("nan")
Christian Heimes99170a52007-12-19 02:07:34 +000017
Benjamin Petersone401c682010-07-02 23:25:44 +000018have_getformat = hasattr(float, "__getformat__")
19requires_getformat = unittest.skipUnless(have_getformat,
20 "requires __getformat__")
21requires_setformat = unittest.skipUnless(hasattr(float, "__setformat__"),
22 "requires __setformat__")
Mark Dickinson9ab44b52009-12-30 16:22:49 +000023
Eric Smith0923d1d2009-04-16 20:16:10 +000024#locate file with float format test values
25test_dir = os.path.dirname(__file__) or os.curdir
26format_testfile = os.path.join(test_dir, 'formatfloat_testcases.txt')
27
Christian Heimes81ee3ef2008-05-04 22:42:01 +000028class GeneralFloatCases(unittest.TestCase):
29
30 def test_float(self):
31 self.assertEqual(float(3.14), 3.14)
32 self.assertEqual(float(314), 314.0)
33 self.assertEqual(float(" 3.14 "), 3.14)
34 self.assertRaises(ValueError, float, " 0x3.1 ")
35 self.assertRaises(ValueError, float, " -0x3.p-1 ")
36 self.assertRaises(ValueError, float, " +0x3.p-1 ")
37 self.assertRaises(ValueError, float, "++3.14")
38 self.assertRaises(ValueError, float, "+-3.14")
39 self.assertRaises(ValueError, float, "-+3.14")
40 self.assertRaises(ValueError, float, "--3.14")
Eric Smith0923d1d2009-04-16 20:16:10 +000041 self.assertRaises(ValueError, float, ".nan")
42 self.assertRaises(ValueError, float, "+.inf")
43 self.assertRaises(ValueError, float, ".")
44 self.assertRaises(ValueError, float, "-.")
Alexander Belopolsky942af5a2010-12-04 03:38:46 +000045 self.assertRaises(TypeError, float, {})
Ezio Melottia5b95992013-11-07 19:18:34 +020046 self.assertRaisesRegex(TypeError, "not 'dict'", float, {})
Alexander Belopolsky942af5a2010-12-04 03:38:46 +000047 # Lone surrogate
48 self.assertRaises(UnicodeEncodeError, float, '\uD8F0')
Mark Dickinsonc2d86892010-02-12 21:18:34 +000049 # check that we don't accept alternate exponent markers
50 self.assertRaises(ValueError, float, "-1.7d29")
51 self.assertRaises(ValueError, float, "3D-14")
Alexander Belopolsky942af5a2010-12-04 03:38:46 +000052 self.assertEqual(float(" \u0663.\u0661\u0664 "), 3.14)
53 self.assertEqual(float("\N{EM SPACE}3.14\N{EN SPACE}"), 3.14)
Mark Dickinsona9023be2009-10-27 22:12:20 +000054 # extra long strings should not be a problem
55 float(b'.' + b'1'*1000)
56 float('.' + '1'*1000)
Christian Heimes81ee3ef2008-05-04 22:42:01 +000057
Martin Pantereeb896c2015-11-07 02:32:21 +000058 def test_non_numeric_input_types(self):
59 # Test possible non-numeric types for the argument x, including
60 # subclasses of the explicitly documented accepted types.
61 class CustomStr(str): pass
62 class CustomBytes(bytes): pass
63 class CustomByteArray(bytearray): pass
64
65 factories = [
66 bytes,
67 bytearray,
68 lambda b: CustomStr(b.decode()),
69 CustomBytes,
70 CustomByteArray,
71 memoryview,
72 ]
73 try:
74 from array import array
75 except ImportError:
76 pass
77 else:
78 factories.append(lambda b: array('B', b))
79
80 for f in factories:
81 x = f(b" 3.14 ")
82 with self.subTest(type(x)):
83 self.assertEqual(float(x), 3.14)
84 with self.assertRaisesRegex(ValueError, "could not convert"):
85 float(f(b'A' * 0x10))
86
87 def test_float_memoryview(self):
88 self.assertEqual(float(memoryview(b'12.3')[1:4]), 2.3)
89 self.assertEqual(float(memoryview(b'12.3\x00')[1:4]), 2.3)
90 self.assertEqual(float(memoryview(b'12.3 ')[1:4]), 2.3)
91 self.assertEqual(float(memoryview(b'12.3A')[1:4]), 2.3)
92 self.assertEqual(float(memoryview(b'12.34')[1:4]), 2.3)
93
Alexander Belopolsky942af5a2010-12-04 03:38:46 +000094 def test_error_message(self):
95 testlist = ('\xbd', '123\xbd', ' 123 456 ')
96 for s in testlist:
97 try:
98 float(s)
99 except ValueError as e:
100 self.assertIn(s.strip(), e.args[0])
101 else:
102 self.fail("Expected int(%r) to raise a ValueError", s)
103
104
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000105 @support.run_with_locale('LC_NUMERIC', 'fr_FR', 'de_DE')
Christian Heimes81ee3ef2008-05-04 22:42:01 +0000106 def test_float_with_comma(self):
107 # set locale to something that doesn't use '.' for the decimal point
108 # float must not accept the locale specific decimal point but
Ezio Melotti13925002011-03-16 11:05:33 +0200109 # it still has to accept the normal python syntax
Christian Heimes81ee3ef2008-05-04 22:42:01 +0000110 import locale
111 if not locale.localeconv()['decimal_point'] == ',':
Zachary Ware9fe6d862013-12-08 00:20:35 -0600112 self.skipTest('decimal_point is not ","')
Christian Heimes81ee3ef2008-05-04 22:42:01 +0000113
114 self.assertEqual(float(" 3.14 "), 3.14)
115 self.assertEqual(float("+3.14 "), 3.14)
116 self.assertEqual(float("-3.14 "), -3.14)
117 self.assertEqual(float(".14 "), .14)
118 self.assertEqual(float("3. "), 3.0)
119 self.assertEqual(float("3.e3 "), 3000.0)
120 self.assertEqual(float("3.2e3 "), 3200.0)
121 self.assertEqual(float("2.5e-1 "), 0.25)
122 self.assertEqual(float("5e-1"), 0.5)
123 self.assertRaises(ValueError, float, " 3,14 ")
124 self.assertRaises(ValueError, float, " +3,14 ")
125 self.assertRaises(ValueError, float, " -3,14 ")
126 self.assertRaises(ValueError, float, " 0x3.1 ")
127 self.assertRaises(ValueError, float, " -0x3.p-1 ")
128 self.assertRaises(ValueError, float, " +0x3.p-1 ")
129 self.assertEqual(float(" 25.e-1 "), 2.5)
Eli Bendersky67ebabd2011-02-25 10:14:17 +0000130 self.assertAlmostEqual(float(" .25e-1 "), .025)
Christian Heimes81ee3ef2008-05-04 22:42:01 +0000131
132 def test_floatconversion(self):
133 # Make sure that calls to __float__() work properly
Christian Heimes81ee3ef2008-05-04 22:42:01 +0000134 class Foo1(object):
135 def __float__(self):
136 return 42.
137
138 class Foo2(float):
139 def __float__(self):
140 return 42.
141
142 class Foo3(float):
143 def __new__(cls, value=0.):
144 return float.__new__(cls, 2*value)
145
146 def __float__(self):
147 return self
148
149 class Foo4(float):
150 def __float__(self):
151 return 42
152
Benjamin Peterson2808d3c2009-04-15 21:34:27 +0000153 # Issue 5759: __float__ not called on str subclasses (though it is on
154 # unicode subclasses).
155 class FooStr(str):
156 def __float__(self):
157 return float(str(self)) + 1
158
Christian Heimes81ee3ef2008-05-04 22:42:01 +0000159 self.assertAlmostEqual(float(Foo1()), 42.)
160 self.assertAlmostEqual(float(Foo2()), 42.)
161 self.assertAlmostEqual(float(Foo3(21)), 42.)
162 self.assertRaises(TypeError, float, Foo4(42))
Benjamin Peterson2808d3c2009-04-15 21:34:27 +0000163 self.assertAlmostEqual(float(FooStr('8')), 9.)
Christian Heimes81ee3ef2008-05-04 22:42:01 +0000164
Benjamin Petersona9157232015-03-06 09:08:44 -0500165 class Foo5:
166 def __float__(self):
167 return ""
168 self.assertRaises(TypeError, time.sleep, Foo5())
169
Benjamin Petersonb3b8ba62011-10-28 19:42:48 -0400170 def test_is_integer(self):
171 self.assertFalse((1.1).is_integer())
172 self.assertTrue((1.).is_integer())
173 self.assertFalse(float("nan").is_integer())
174 self.assertFalse(float("inf").is_integer())
175
Christian Heimes81ee3ef2008-05-04 22:42:01 +0000176 def test_floatasratio(self):
177 for f, ratio in [
178 (0.875, (7, 8)),
179 (-0.875, (-7, 8)),
180 (0.0, (0, 1)),
181 (11.5, (23, 2)),
182 ]:
183 self.assertEqual(f.as_integer_ratio(), ratio)
184
185 for i in range(10000):
186 f = random.random()
187 f *= 10 ** random.randint(-100, 100)
188 n, d = f.as_integer_ratio()
189 self.assertEqual(float(n).__truediv__(d), f)
190
191 R = fractions.Fraction
192 self.assertEqual(R(0, 1),
193 R(*float(0.0).as_integer_ratio()))
194 self.assertEqual(R(5, 2),
195 R(*float(2.5).as_integer_ratio()))
196 self.assertEqual(R(1, 2),
197 R(*float(0.5).as_integer_ratio()))
198 self.assertEqual(R(4728779608739021, 2251799813685248),
199 R(*float(2.1).as_integer_ratio()))
200 self.assertEqual(R(-4728779608739021, 2251799813685248),
201 R(*float(-2.1).as_integer_ratio()))
202 self.assertEqual(R(-2100, 1),
203 R(*float(-2100.0).as_integer_ratio()))
204
205 self.assertRaises(OverflowError, float('inf').as_integer_ratio)
206 self.assertRaises(OverflowError, float('-inf').as_integer_ratio)
207 self.assertRaises(ValueError, float('nan').as_integer_ratio)
208
Mark Dickinson4a1f5932008-11-12 23:23:36 +0000209 def test_float_containment(self):
210 floats = (INF, -INF, 0.0, 1.0, NAN)
211 for f in floats:
Benjamin Peterson577473f2010-01-19 00:09:57 +0000212 self.assertIn(f, [f])
Benjamin Peterson577473f2010-01-19 00:09:57 +0000213 self.assertIn(f, (f,))
Benjamin Peterson577473f2010-01-19 00:09:57 +0000214 self.assertIn(f, {f})
Benjamin Peterson577473f2010-01-19 00:09:57 +0000215 self.assertIn(f, {f: None})
Mark Dickinson4a1f5932008-11-12 23:23:36 +0000216 self.assertEqual([f].count(f), 1, "[].count('%r') != 1" % f)
Benjamin Peterson577473f2010-01-19 00:09:57 +0000217 self.assertIn(f, floats)
Mark Dickinson4a1f5932008-11-12 23:23:36 +0000218
219 for f in floats:
220 # nonidentical containers, same type, same contents
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000221 self.assertTrue([f] == [f], "[%r] != [%r]" % (f, f))
222 self.assertTrue((f,) == (f,), "(%r,) != (%r,)" % (f, f))
223 self.assertTrue({f} == {f}, "{%r} != {%r}" % (f, f))
224 self.assertTrue({f : None} == {f: None}, "{%r : None} != "
Mark Dickinson4a1f5932008-11-12 23:23:36 +0000225 "{%r : None}" % (f, f))
226
227 # identical containers
228 l, t, s, d = [f], (f,), {f}, {f: None}
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000229 self.assertTrue(l == l, "[%r] not equal to itself" % f)
230 self.assertTrue(t == t, "(%r,) not equal to itself" % f)
231 self.assertTrue(s == s, "{%r} not equal to itself" % f)
232 self.assertTrue(d == d, "{%r : None} not equal to itself" % f)
Mark Dickinson4a1f5932008-11-12 23:23:36 +0000233
Mark Dickinson9ab44b52009-12-30 16:22:49 +0000234 def assertEqualAndEqualSign(self, a, b):
235 # fail unless a == b and a and b have the same sign bit;
236 # the only difference from assertEqual is that this test
Ezio Melotti13925002011-03-16 11:05:33 +0200237 # distinguishes -0.0 and 0.0.
Mark Dickinson9ab44b52009-12-30 16:22:49 +0000238 self.assertEqual((a, copysign(1.0, a)), (b, copysign(1.0, b)))
239
Eric Smith3ab08ca2010-12-04 15:17:38 +0000240 @support.requires_IEEE_754
Mark Dickinsond2a9b202010-12-04 12:25:30 +0000241 def test_float_mod(self):
242 # Check behaviour of % operator for IEEE 754 special cases.
243 # In particular, check signs of zeros.
244 mod = operator.mod
245
246 self.assertEqualAndEqualSign(mod(-1.0, 1.0), 0.0)
247 self.assertEqualAndEqualSign(mod(-1e-100, 1.0), 1.0)
248 self.assertEqualAndEqualSign(mod(-0.0, 1.0), 0.0)
249 self.assertEqualAndEqualSign(mod(0.0, 1.0), 0.0)
250 self.assertEqualAndEqualSign(mod(1e-100, 1.0), 1e-100)
251 self.assertEqualAndEqualSign(mod(1.0, 1.0), 0.0)
252
253 self.assertEqualAndEqualSign(mod(-1.0, -1.0), -0.0)
254 self.assertEqualAndEqualSign(mod(-1e-100, -1.0), -1e-100)
255 self.assertEqualAndEqualSign(mod(-0.0, -1.0), -0.0)
256 self.assertEqualAndEqualSign(mod(0.0, -1.0), -0.0)
257 self.assertEqualAndEqualSign(mod(1e-100, -1.0), -1.0)
258 self.assertEqualAndEqualSign(mod(1.0, -1.0), -0.0)
259
Eric Smith3ab08ca2010-12-04 15:17:38 +0000260 @support.requires_IEEE_754
Mark Dickinson9ab44b52009-12-30 16:22:49 +0000261 def test_float_pow(self):
262 # test builtin pow and ** operator for IEEE 754 special cases.
263 # Special cases taken from section F.9.4.4 of the C99 specification
264
265 for pow_op in pow, operator.pow:
266 # x**NAN is NAN for any x except 1
267 self.assertTrue(isnan(pow_op(-INF, NAN)))
268 self.assertTrue(isnan(pow_op(-2.0, NAN)))
269 self.assertTrue(isnan(pow_op(-1.0, NAN)))
270 self.assertTrue(isnan(pow_op(-0.5, NAN)))
271 self.assertTrue(isnan(pow_op(-0.0, NAN)))
272 self.assertTrue(isnan(pow_op(0.0, NAN)))
273 self.assertTrue(isnan(pow_op(0.5, NAN)))
274 self.assertTrue(isnan(pow_op(2.0, NAN)))
275 self.assertTrue(isnan(pow_op(INF, NAN)))
276 self.assertTrue(isnan(pow_op(NAN, NAN)))
277
278 # NAN**y is NAN for any y except +-0
279 self.assertTrue(isnan(pow_op(NAN, -INF)))
280 self.assertTrue(isnan(pow_op(NAN, -2.0)))
281 self.assertTrue(isnan(pow_op(NAN, -1.0)))
282 self.assertTrue(isnan(pow_op(NAN, -0.5)))
283 self.assertTrue(isnan(pow_op(NAN, 0.5)))
284 self.assertTrue(isnan(pow_op(NAN, 1.0)))
285 self.assertTrue(isnan(pow_op(NAN, 2.0)))
286 self.assertTrue(isnan(pow_op(NAN, INF)))
287
288 # (+-0)**y raises ZeroDivisionError for y a negative odd integer
289 self.assertRaises(ZeroDivisionError, pow_op, -0.0, -1.0)
290 self.assertRaises(ZeroDivisionError, pow_op, 0.0, -1.0)
291
292 # (+-0)**y raises ZeroDivisionError for y finite and negative
293 # but not an odd integer
294 self.assertRaises(ZeroDivisionError, pow_op, -0.0, -2.0)
295 self.assertRaises(ZeroDivisionError, pow_op, -0.0, -0.5)
296 self.assertRaises(ZeroDivisionError, pow_op, 0.0, -2.0)
297 self.assertRaises(ZeroDivisionError, pow_op, 0.0, -0.5)
298
299 # (+-0)**y is +-0 for y a positive odd integer
300 self.assertEqualAndEqualSign(pow_op(-0.0, 1.0), -0.0)
301 self.assertEqualAndEqualSign(pow_op(0.0, 1.0), 0.0)
302
303 # (+-0)**y is 0 for y finite and positive but not an odd integer
304 self.assertEqualAndEqualSign(pow_op(-0.0, 0.5), 0.0)
305 self.assertEqualAndEqualSign(pow_op(-0.0, 2.0), 0.0)
306 self.assertEqualAndEqualSign(pow_op(0.0, 0.5), 0.0)
307 self.assertEqualAndEqualSign(pow_op(0.0, 2.0), 0.0)
308
309 # (-1)**+-inf is 1
310 self.assertEqualAndEqualSign(pow_op(-1.0, -INF), 1.0)
311 self.assertEqualAndEqualSign(pow_op(-1.0, INF), 1.0)
312
313 # 1**y is 1 for any y, even if y is an infinity or nan
314 self.assertEqualAndEqualSign(pow_op(1.0, -INF), 1.0)
315 self.assertEqualAndEqualSign(pow_op(1.0, -2.0), 1.0)
316 self.assertEqualAndEqualSign(pow_op(1.0, -1.0), 1.0)
317 self.assertEqualAndEqualSign(pow_op(1.0, -0.5), 1.0)
318 self.assertEqualAndEqualSign(pow_op(1.0, -0.0), 1.0)
319 self.assertEqualAndEqualSign(pow_op(1.0, 0.0), 1.0)
320 self.assertEqualAndEqualSign(pow_op(1.0, 0.5), 1.0)
321 self.assertEqualAndEqualSign(pow_op(1.0, 1.0), 1.0)
322 self.assertEqualAndEqualSign(pow_op(1.0, 2.0), 1.0)
323 self.assertEqualAndEqualSign(pow_op(1.0, INF), 1.0)
324 self.assertEqualAndEqualSign(pow_op(1.0, NAN), 1.0)
325
326 # x**+-0 is 1 for any x, even if x is a zero, infinity, or nan
327 self.assertEqualAndEqualSign(pow_op(-INF, 0.0), 1.0)
328 self.assertEqualAndEqualSign(pow_op(-2.0, 0.0), 1.0)
329 self.assertEqualAndEqualSign(pow_op(-1.0, 0.0), 1.0)
330 self.assertEqualAndEqualSign(pow_op(-0.5, 0.0), 1.0)
331 self.assertEqualAndEqualSign(pow_op(-0.0, 0.0), 1.0)
332 self.assertEqualAndEqualSign(pow_op(0.0, 0.0), 1.0)
333 self.assertEqualAndEqualSign(pow_op(0.5, 0.0), 1.0)
334 self.assertEqualAndEqualSign(pow_op(1.0, 0.0), 1.0)
335 self.assertEqualAndEqualSign(pow_op(2.0, 0.0), 1.0)
336 self.assertEqualAndEqualSign(pow_op(INF, 0.0), 1.0)
337 self.assertEqualAndEqualSign(pow_op(NAN, 0.0), 1.0)
338 self.assertEqualAndEqualSign(pow_op(-INF, -0.0), 1.0)
339 self.assertEqualAndEqualSign(pow_op(-2.0, -0.0), 1.0)
340 self.assertEqualAndEqualSign(pow_op(-1.0, -0.0), 1.0)
341 self.assertEqualAndEqualSign(pow_op(-0.5, -0.0), 1.0)
342 self.assertEqualAndEqualSign(pow_op(-0.0, -0.0), 1.0)
343 self.assertEqualAndEqualSign(pow_op(0.0, -0.0), 1.0)
344 self.assertEqualAndEqualSign(pow_op(0.5, -0.0), 1.0)
345 self.assertEqualAndEqualSign(pow_op(1.0, -0.0), 1.0)
346 self.assertEqualAndEqualSign(pow_op(2.0, -0.0), 1.0)
347 self.assertEqualAndEqualSign(pow_op(INF, -0.0), 1.0)
348 self.assertEqualAndEqualSign(pow_op(NAN, -0.0), 1.0)
349
350 # x**y defers to complex pow for finite negative x and
351 # non-integral y.
352 self.assertEqual(type(pow_op(-2.0, -0.5)), complex)
353 self.assertEqual(type(pow_op(-2.0, 0.5)), complex)
354 self.assertEqual(type(pow_op(-1.0, -0.5)), complex)
355 self.assertEqual(type(pow_op(-1.0, 0.5)), complex)
356 self.assertEqual(type(pow_op(-0.5, -0.5)), complex)
357 self.assertEqual(type(pow_op(-0.5, 0.5)), complex)
358
359 # x**-INF is INF for abs(x) < 1
360 self.assertEqualAndEqualSign(pow_op(-0.5, -INF), INF)
361 self.assertEqualAndEqualSign(pow_op(-0.0, -INF), INF)
362 self.assertEqualAndEqualSign(pow_op(0.0, -INF), INF)
363 self.assertEqualAndEqualSign(pow_op(0.5, -INF), INF)
364
365 # x**-INF is 0 for abs(x) > 1
366 self.assertEqualAndEqualSign(pow_op(-INF, -INF), 0.0)
367 self.assertEqualAndEqualSign(pow_op(-2.0, -INF), 0.0)
368 self.assertEqualAndEqualSign(pow_op(2.0, -INF), 0.0)
369 self.assertEqualAndEqualSign(pow_op(INF, -INF), 0.0)
370
371 # x**INF is 0 for abs(x) < 1
372 self.assertEqualAndEqualSign(pow_op(-0.5, INF), 0.0)
373 self.assertEqualAndEqualSign(pow_op(-0.0, INF), 0.0)
374 self.assertEqualAndEqualSign(pow_op(0.0, INF), 0.0)
375 self.assertEqualAndEqualSign(pow_op(0.5, INF), 0.0)
376
377 # x**INF is INF for abs(x) > 1
378 self.assertEqualAndEqualSign(pow_op(-INF, INF), INF)
379 self.assertEqualAndEqualSign(pow_op(-2.0, INF), INF)
380 self.assertEqualAndEqualSign(pow_op(2.0, INF), INF)
381 self.assertEqualAndEqualSign(pow_op(INF, INF), INF)
382
383 # (-INF)**y is -0.0 for y a negative odd integer
384 self.assertEqualAndEqualSign(pow_op(-INF, -1.0), -0.0)
385
386 # (-INF)**y is 0.0 for y negative but not an odd integer
387 self.assertEqualAndEqualSign(pow_op(-INF, -0.5), 0.0)
388 self.assertEqualAndEqualSign(pow_op(-INF, -2.0), 0.0)
389
390 # (-INF)**y is -INF for y a positive odd integer
391 self.assertEqualAndEqualSign(pow_op(-INF, 1.0), -INF)
392
393 # (-INF)**y is INF for y positive but not an odd integer
394 self.assertEqualAndEqualSign(pow_op(-INF, 0.5), INF)
395 self.assertEqualAndEqualSign(pow_op(-INF, 2.0), INF)
396
397 # INF**y is INF for y positive
398 self.assertEqualAndEqualSign(pow_op(INF, 0.5), INF)
399 self.assertEqualAndEqualSign(pow_op(INF, 1.0), INF)
400 self.assertEqualAndEqualSign(pow_op(INF, 2.0), INF)
401
402 # INF**y is 0.0 for y negative
403 self.assertEqualAndEqualSign(pow_op(INF, -2.0), 0.0)
404 self.assertEqualAndEqualSign(pow_op(INF, -1.0), 0.0)
405 self.assertEqualAndEqualSign(pow_op(INF, -0.5), 0.0)
406
407 # basic checks not covered by the special cases above
408 self.assertEqualAndEqualSign(pow_op(-2.0, -2.0), 0.25)
409 self.assertEqualAndEqualSign(pow_op(-2.0, -1.0), -0.5)
410 self.assertEqualAndEqualSign(pow_op(-2.0, -0.0), 1.0)
411 self.assertEqualAndEqualSign(pow_op(-2.0, 0.0), 1.0)
412 self.assertEqualAndEqualSign(pow_op(-2.0, 1.0), -2.0)
413 self.assertEqualAndEqualSign(pow_op(-2.0, 2.0), 4.0)
414 self.assertEqualAndEqualSign(pow_op(-1.0, -2.0), 1.0)
415 self.assertEqualAndEqualSign(pow_op(-1.0, -1.0), -1.0)
416 self.assertEqualAndEqualSign(pow_op(-1.0, -0.0), 1.0)
417 self.assertEqualAndEqualSign(pow_op(-1.0, 0.0), 1.0)
418 self.assertEqualAndEqualSign(pow_op(-1.0, 1.0), -1.0)
419 self.assertEqualAndEqualSign(pow_op(-1.0, 2.0), 1.0)
420 self.assertEqualAndEqualSign(pow_op(2.0, -2.0), 0.25)
421 self.assertEqualAndEqualSign(pow_op(2.0, -1.0), 0.5)
422 self.assertEqualAndEqualSign(pow_op(2.0, -0.0), 1.0)
423 self.assertEqualAndEqualSign(pow_op(2.0, 0.0), 1.0)
424 self.assertEqualAndEqualSign(pow_op(2.0, 1.0), 2.0)
425 self.assertEqualAndEqualSign(pow_op(2.0, 2.0), 4.0)
426
427 # 1 ** large and -1 ** large; some libms apparently
428 # have problems with these
429 self.assertEqualAndEqualSign(pow_op(1.0, -1e100), 1.0)
430 self.assertEqualAndEqualSign(pow_op(1.0, 1e100), 1.0)
431 self.assertEqualAndEqualSign(pow_op(-1.0, -1e100), 1.0)
432 self.assertEqualAndEqualSign(pow_op(-1.0, 1e100), 1.0)
433
434 # check sign for results that underflow to 0
435 self.assertEqualAndEqualSign(pow_op(-2.0, -2000.0), 0.0)
436 self.assertEqual(type(pow_op(-2.0, -2000.5)), complex)
437 self.assertEqualAndEqualSign(pow_op(-2.0, -2001.0), -0.0)
438 self.assertEqualAndEqualSign(pow_op(2.0, -2000.0), 0.0)
439 self.assertEqualAndEqualSign(pow_op(2.0, -2000.5), 0.0)
440 self.assertEqualAndEqualSign(pow_op(2.0, -2001.0), 0.0)
441 self.assertEqualAndEqualSign(pow_op(-0.5, 2000.0), 0.0)
442 self.assertEqual(type(pow_op(-0.5, 2000.5)), complex)
443 self.assertEqualAndEqualSign(pow_op(-0.5, 2001.0), -0.0)
444 self.assertEqualAndEqualSign(pow_op(0.5, 2000.0), 0.0)
445 self.assertEqualAndEqualSign(pow_op(0.5, 2000.5), 0.0)
446 self.assertEqualAndEqualSign(pow_op(0.5, 2001.0), 0.0)
447
448 # check we don't raise an exception for subnormal results,
449 # and validate signs. Tests currently disabled, since
450 # they fail on systems where a subnormal result from pow
451 # is flushed to zero (e.g. Debian/ia64.)
452 #self.assertTrue(0.0 < pow_op(0.5, 1048) < 1e-315)
453 #self.assertTrue(0.0 < pow_op(-0.5, 1048) < 1e-315)
454 #self.assertTrue(0.0 < pow_op(0.5, 1047) < 1e-315)
455 #self.assertTrue(0.0 > pow_op(-0.5, 1047) > -1e-315)
456 #self.assertTrue(0.0 < pow_op(2.0, -1048) < 1e-315)
457 #self.assertTrue(0.0 < pow_op(-2.0, -1048) < 1e-315)
458 #self.assertTrue(0.0 < pow_op(2.0, -1047) < 1e-315)
459 #self.assertTrue(0.0 > pow_op(-2.0, -1047) > -1e-315)
Mark Dickinson4a1f5932008-11-12 23:23:36 +0000460
461
Benjamin Petersone401c682010-07-02 23:25:44 +0000462@requires_setformat
Michael W. Hudsonba283e22005-05-27 15:23:20 +0000463class FormatFunctionsTestCase(unittest.TestCase):
464
465 def setUp(self):
466 self.save_formats = {'double':float.__getformat__('double'),
467 'float':float.__getformat__('float')}
468
469 def tearDown(self):
470 float.__setformat__('double', self.save_formats['double'])
471 float.__setformat__('float', self.save_formats['float'])
472
473 def test_getformat(self):
Ezio Melottib58e0bd2010-01-23 15:40:09 +0000474 self.assertIn(float.__getformat__('double'),
475 ['unknown', 'IEEE, big-endian', 'IEEE, little-endian'])
476 self.assertIn(float.__getformat__('float'),
477 ['unknown', 'IEEE, big-endian', 'IEEE, little-endian'])
Michael W. Hudsonba283e22005-05-27 15:23:20 +0000478 self.assertRaises(ValueError, float.__getformat__, 'chicken')
479 self.assertRaises(TypeError, float.__getformat__, 1)
480
481 def test_setformat(self):
482 for t in 'double', 'float':
483 float.__setformat__(t, 'unknown')
484 if self.save_formats[t] == 'IEEE, big-endian':
485 self.assertRaises(ValueError, float.__setformat__,
486 t, 'IEEE, little-endian')
487 elif self.save_formats[t] == 'IEEE, little-endian':
488 self.assertRaises(ValueError, float.__setformat__,
489 t, 'IEEE, big-endian')
490 else:
491 self.assertRaises(ValueError, float.__setformat__,
492 t, 'IEEE, big-endian')
493 self.assertRaises(ValueError, float.__setformat__,
494 t, 'IEEE, little-endian')
495 self.assertRaises(ValueError, float.__setformat__,
496 t, 'chicken')
497 self.assertRaises(ValueError, float.__setformat__,
498 'chicken', 'unknown')
499
Guido van Rossum2be161d2007-05-15 20:43:51 +0000500BE_DOUBLE_INF = b'\x7f\xf0\x00\x00\x00\x00\x00\x00'
Guido van Rossum254348e2007-11-21 19:29:53 +0000501LE_DOUBLE_INF = bytes(reversed(BE_DOUBLE_INF))
Guido van Rossum2be161d2007-05-15 20:43:51 +0000502BE_DOUBLE_NAN = b'\x7f\xf8\x00\x00\x00\x00\x00\x00'
Guido van Rossum254348e2007-11-21 19:29:53 +0000503LE_DOUBLE_NAN = bytes(reversed(BE_DOUBLE_NAN))
Michael W. Hudsonba283e22005-05-27 15:23:20 +0000504
Guido van Rossum2be161d2007-05-15 20:43:51 +0000505BE_FLOAT_INF = b'\x7f\x80\x00\x00'
Guido van Rossum254348e2007-11-21 19:29:53 +0000506LE_FLOAT_INF = bytes(reversed(BE_FLOAT_INF))
Guido van Rossum2be161d2007-05-15 20:43:51 +0000507BE_FLOAT_NAN = b'\x7f\xc0\x00\x00'
Guido van Rossum254348e2007-11-21 19:29:53 +0000508LE_FLOAT_NAN = bytes(reversed(BE_FLOAT_NAN))
Michael W. Hudsonba283e22005-05-27 15:23:20 +0000509
510# on non-IEEE platforms, attempting to unpack a bit pattern
511# representing an infinity or a NaN should raise an exception.
512
Benjamin Petersone401c682010-07-02 23:25:44 +0000513@requires_setformat
Michael W. Hudsonba283e22005-05-27 15:23:20 +0000514class UnknownFormatTestCase(unittest.TestCase):
515 def setUp(self):
516 self.save_formats = {'double':float.__getformat__('double'),
517 'float':float.__getformat__('float')}
518 float.__setformat__('double', 'unknown')
519 float.__setformat__('float', 'unknown')
Tim Peters5d36a552005-06-03 22:40:27 +0000520
Michael W. Hudsonba283e22005-05-27 15:23:20 +0000521 def tearDown(self):
522 float.__setformat__('double', self.save_formats['double'])
523 float.__setformat__('float', self.save_formats['float'])
524
525 def test_double_specials_dont_unpack(self):
526 for fmt, data in [('>d', BE_DOUBLE_INF),
527 ('>d', BE_DOUBLE_NAN),
528 ('<d', LE_DOUBLE_INF),
529 ('<d', LE_DOUBLE_NAN)]:
530 self.assertRaises(ValueError, struct.unpack, fmt, data)
531
532 def test_float_specials_dont_unpack(self):
533 for fmt, data in [('>f', BE_FLOAT_INF),
534 ('>f', BE_FLOAT_NAN),
535 ('<f', LE_FLOAT_INF),
536 ('<f', LE_FLOAT_NAN)]:
537 self.assertRaises(ValueError, struct.unpack, fmt, data)
538
539
540# on an IEEE platform, all we guarantee is that bit patterns
541# representing infinities or NaNs do not raise an exception; all else
542# is accident (today).
Guido van Rossum04110fb2007-08-24 16:32:05 +0000543# let's also try to guarantee that -0.0 and 0.0 don't get confused.
Michael W. Hudsonba283e22005-05-27 15:23:20 +0000544
545class IEEEFormatTestCase(unittest.TestCase):
Michael W. Hudsonba283e22005-05-27 15:23:20 +0000546
Eric Smith3ab08ca2010-12-04 15:17:38 +0000547 @support.requires_IEEE_754
Benjamin Petersone401c682010-07-02 23:25:44 +0000548 def test_double_specials_do_unpack(self):
549 for fmt, data in [('>d', BE_DOUBLE_INF),
550 ('>d', BE_DOUBLE_NAN),
551 ('<d', LE_DOUBLE_INF),
552 ('<d', LE_DOUBLE_NAN)]:
553 struct.unpack(fmt, data)
Michael W. Hudsonba283e22005-05-27 15:23:20 +0000554
Eric Smith3ab08ca2010-12-04 15:17:38 +0000555 @support.requires_IEEE_754
Benjamin Petersone401c682010-07-02 23:25:44 +0000556 def test_float_specials_do_unpack(self):
557 for fmt, data in [('>f', BE_FLOAT_INF),
558 ('>f', BE_FLOAT_NAN),
559 ('<f', LE_FLOAT_INF),
560 ('<f', LE_FLOAT_NAN)]:
561 struct.unpack(fmt, data)
Guido van Rossum04110fb2007-08-24 16:32:05 +0000562
Eric Smith8c663262007-08-25 02:26:07 +0000563class FormatTestCase(unittest.TestCase):
Benjamin Petersone401c682010-07-02 23:25:44 +0000564
Eric Smith11fe3e02007-08-31 01:33:06 +0000565 def test_format(self):
Eric Smith8c663262007-08-25 02:26:07 +0000566 # these should be rewritten to use both format(x, spec) and
567 # x.__format__(spec)
568
569 self.assertEqual(format(0.0, 'f'), '0.000000')
570
571 # the default is 'g', except for empty format spec
572 self.assertEqual(format(0.0, ''), '0.0')
573 self.assertEqual(format(0.01, ''), '0.01')
574 self.assertEqual(format(0.01, 'g'), '0.01')
575
Eric Smith63376222009-05-05 14:04:18 +0000576 # empty presentation type should format in the same way as str
577 # (issue 5920)
578 x = 100/7.
579 self.assertEqual(format(x, ''), str(x))
580 self.assertEqual(format(x, '-'), str(x))
581 self.assertEqual(format(x, '>'), str(x))
582 self.assertEqual(format(x, '2'), str(x))
Eric Smith8c663262007-08-25 02:26:07 +0000583
584 self.assertEqual(format(1.0, 'f'), '1.000000')
Eric Smith8c663262007-08-25 02:26:07 +0000585
586 self.assertEqual(format(-1.0, 'f'), '-1.000000')
Eric Smith8c663262007-08-25 02:26:07 +0000587
588 self.assertEqual(format( 1.0, ' f'), ' 1.000000')
589 self.assertEqual(format(-1.0, ' f'), '-1.000000')
590 self.assertEqual(format( 1.0, '+f'), '+1.000000')
591 self.assertEqual(format(-1.0, '+f'), '-1.000000')
592
593 # % formatting
594 self.assertEqual(format(-1.0, '%'), '-100.000000%')
595
596 # conversion to string should fail
597 self.assertRaises(ValueError, format, 3.0, "s")
598
Eric Smith7b69c6c2008-01-27 21:07:59 +0000599 # other format specifiers shouldn't work on floats,
600 # in particular int specifiers
601 for format_spec in ([chr(x) for x in range(ord('a'), ord('z')+1)] +
602 [chr(x) for x in range(ord('A'), ord('Z')+1)]):
603 if not format_spec in 'eEfFgGn%':
604 self.assertRaises(ValueError, format, 0.0, format_spec)
605 self.assertRaises(ValueError, format, 1.0, format_spec)
606 self.assertRaises(ValueError, format, -1.0, format_spec)
607 self.assertRaises(ValueError, format, 1e100, format_spec)
608 self.assertRaises(ValueError, format, -1e100, format_spec)
609 self.assertRaises(ValueError, format, 1e-100, format_spec)
610 self.assertRaises(ValueError, format, -1e-100, format_spec)
Michael W. Hudsonba283e22005-05-27 15:23:20 +0000611
Eric Smith741191f2009-05-06 13:08:15 +0000612 # issue 3382
613 self.assertEqual(format(NAN, 'f'), 'nan')
614 self.assertEqual(format(NAN, 'F'), 'NAN')
615 self.assertEqual(format(INF, 'f'), 'inf')
616 self.assertEqual(format(INF, 'F'), 'INF')
617
Eric Smith3ab08ca2010-12-04 15:17:38 +0000618 @support.requires_IEEE_754
Eric Smith0923d1d2009-04-16 20:16:10 +0000619 def test_format_testfile(self):
Brian Curtin076623b2010-10-31 00:03:45 +0000620 with open(format_testfile) as testfile:
621 for line in testfile:
622 if line.startswith('--'):
623 continue
624 line = line.strip()
625 if not line:
626 continue
Eric Smith0923d1d2009-04-16 20:16:10 +0000627
Brian Curtin076623b2010-10-31 00:03:45 +0000628 lhs, rhs = map(str.strip, line.split('->'))
629 fmt, arg = lhs.split()
630 self.assertEqual(fmt % float(arg), rhs)
631 self.assertEqual(fmt % -float(arg), '-' + rhs)
Eric Smith0923d1d2009-04-16 20:16:10 +0000632
Mark Dickinsond3ca5572009-04-29 18:47:07 +0000633 def test_issue5864(self):
Ezio Melottib3aedd42010-11-20 19:04:17 +0000634 self.assertEqual(format(123.456, '.4'), '123.5')
635 self.assertEqual(format(1234.56, '.4'), '1.235e+03')
636 self.assertEqual(format(12345.6, '.4'), '1.235e+04')
Mark Dickinsond3ca5572009-04-29 18:47:07 +0000637
Mark Dickinson7efad9e2009-04-17 20:59:58 +0000638class ReprTestCase(unittest.TestCase):
639 def test_repr(self):
640 floats_file = open(os.path.join(os.path.split(__file__)[0],
641 'floating_points.txt'))
642 for line in floats_file:
643 line = line.strip()
644 if not line or line.startswith('#'):
645 continue
646 v = eval(line)
647 self.assertEqual(v, eval(repr(v)))
648 floats_file.close()
649
Eric Smith0923d1d2009-04-16 20:16:10 +0000650 @unittest.skipUnless(getattr(sys, 'float_repr_style', '') == 'short',
651 "applies only when using short float repr style")
652 def test_short_repr(self):
653 # test short float repr introduced in Python 3.1. One aspect
654 # of this repr is that we get some degree of str -> float ->
655 # str roundtripping. In particular, for any numeric string
656 # containing 15 or fewer significant digits, those exact same
657 # digits (modulo trailing zeros) should appear in the output.
658 # No more repr(0.03) -> "0.029999999999999999"!
659
660 test_strings = [
661 # output always includes *either* a decimal point and at
662 # least one digit after that point, or an exponent.
663 '0.0',
664 '1.0',
665 '0.01',
666 '0.02',
667 '0.03',
668 '0.04',
669 '0.05',
670 '1.23456789',
671 '10.0',
672 '100.0',
673 # values >= 1e16 get an exponent...
674 '1000000000000000.0',
675 '9999999999999990.0',
676 '1e+16',
677 '1e+17',
678 # ... and so do values < 1e-4
679 '0.001',
680 '0.001001',
681 '0.00010000000000001',
682 '0.0001',
683 '9.999999999999e-05',
684 '1e-05',
685 # values designed to provoke failure if the FPU rounding
686 # precision isn't set correctly
687 '8.72293771110361e+25',
688 '7.47005307342313e+26',
689 '2.86438000439698e+28',
690 '8.89142905246179e+28',
691 '3.08578087079232e+35',
692 ]
693
694 for s in test_strings:
695 negs = '-'+s
696 self.assertEqual(s, repr(float(s)))
697 self.assertEqual(negs, repr(float(negs)))
Mark Dickinson388122d2010-08-04 20:56:28 +0000698 # Since Python 3.2, repr and str are identical
699 self.assertEqual(repr(float(s)), str(float(s)))
700 self.assertEqual(repr(float(negs)), str(float(negs)))
Benjamin Petersone401c682010-07-02 23:25:44 +0000701
Eric Smith3ab08ca2010-12-04 15:17:38 +0000702@support.requires_IEEE_754
Mark Dickinsone6a076d2009-04-18 11:48:33 +0000703class RoundTestCase(unittest.TestCase):
Benjamin Petersone401c682010-07-02 23:25:44 +0000704
Mark Dickinsone6a076d2009-04-18 11:48:33 +0000705 def test_inf_nan(self):
706 self.assertRaises(OverflowError, round, INF)
707 self.assertRaises(OverflowError, round, -INF)
708 self.assertRaises(ValueError, round, NAN)
Mark Dickinson4ca33d12009-11-24 10:59:34 +0000709 self.assertRaises(TypeError, round, INF, 0.0)
710 self.assertRaises(TypeError, round, -INF, 1.0)
711 self.assertRaises(TypeError, round, NAN, "ceci n'est pas un integer")
712 self.assertRaises(TypeError, round, -0.0, 1j)
Mark Dickinsone6a076d2009-04-18 11:48:33 +0000713
Mark Dickinsone6a076d2009-04-18 11:48:33 +0000714 def test_large_n(self):
715 for n in [324, 325, 400, 2**31-1, 2**31, 2**32, 2**100]:
716 self.assertEqual(round(123.456, n), 123.456)
717 self.assertEqual(round(-123.456, n), -123.456)
718 self.assertEqual(round(1e300, n), 1e300)
719 self.assertEqual(round(1e-320, n), 1e-320)
720 self.assertEqual(round(1e150, 300), 1e150)
721 self.assertEqual(round(1e300, 307), 1e300)
722 self.assertEqual(round(-3.1415, 308), -3.1415)
723 self.assertEqual(round(1e150, 309), 1e150)
724 self.assertEqual(round(1.4e-315, 315), 1e-315)
725
Mark Dickinsone6a076d2009-04-18 11:48:33 +0000726 def test_small_n(self):
727 for n in [-308, -309, -400, 1-2**31, -2**31, -2**31-1, -2**100]:
728 self.assertEqual(round(123.456, n), 0.0)
729 self.assertEqual(round(-123.456, n), -0.0)
730 self.assertEqual(round(1e300, n), 0.0)
731 self.assertEqual(round(1e-320, n), 0.0)
732
Mark Dickinsone6a076d2009-04-18 11:48:33 +0000733 def test_overflow(self):
734 self.assertRaises(OverflowError, round, 1.6e308, -308)
735 self.assertRaises(OverflowError, round, -1.7e308, -308)
736
737 @unittest.skipUnless(getattr(sys, 'float_repr_style', '') == 'short',
738 "applies only when using short float repr style")
739 def test_previous_round_bugs(self):
740 # particular cases that have occurred in bug reports
741 self.assertEqual(round(562949953421312.5, 1),
742 562949953421312.5)
743 self.assertEqual(round(56294995342131.5, 3),
744 56294995342131.5)
745 # round-half-even
746 self.assertEqual(round(25.0, -1), 20.0)
747 self.assertEqual(round(35.0, -1), 40.0)
748 self.assertEqual(round(45.0, -1), 40.0)
749 self.assertEqual(round(55.0, -1), 60.0)
750 self.assertEqual(round(65.0, -1), 60.0)
751 self.assertEqual(round(75.0, -1), 80.0)
752 self.assertEqual(round(85.0, -1), 80.0)
753 self.assertEqual(round(95.0, -1), 100.0)
754
755 @unittest.skipUnless(getattr(sys, 'float_repr_style', '') == 'short',
756 "applies only when using short float repr style")
757 def test_matches_float_format(self):
758 # round should give the same results as float formatting
759 for i in range(500):
760 x = i/1000.
761 self.assertEqual(float(format(x, '.0f')), round(x, 0))
762 self.assertEqual(float(format(x, '.1f')), round(x, 1))
763 self.assertEqual(float(format(x, '.2f')), round(x, 2))
764 self.assertEqual(float(format(x, '.3f')), round(x, 3))
765
766 for i in range(5, 5000, 10):
767 x = i/1000.
768 self.assertEqual(float(format(x, '.0f')), round(x, 0))
769 self.assertEqual(float(format(x, '.1f')), round(x, 1))
770 self.assertEqual(float(format(x, '.2f')), round(x, 2))
771 self.assertEqual(float(format(x, '.3f')), round(x, 3))
772
773 for i in range(500):
774 x = random.random()
775 self.assertEqual(float(format(x, '.0f')), round(x, 0))
776 self.assertEqual(float(format(x, '.1f')), round(x, 1))
777 self.assertEqual(float(format(x, '.2f')), round(x, 2))
778 self.assertEqual(float(format(x, '.3f')), round(x, 3))
779
Eric Smith8a10ecc2009-12-02 17:58:24 +0000780 def test_format_specials(self):
781 # Test formatting of nans and infs.
782
783 def test(fmt, value, expected):
784 # Test with both % and format().
785 self.assertEqual(fmt % value, expected, fmt)
Eric Smith984bb582010-11-25 16:08:06 +0000786 fmt = fmt[1:] # strip off the %
787 self.assertEqual(format(value, fmt), expected, fmt)
Eric Smith8a10ecc2009-12-02 17:58:24 +0000788
789 for fmt in ['%e', '%f', '%g', '%.0e', '%.6f', '%.20g',
790 '%#e', '%#f', '%#g', '%#.20e', '%#.15f', '%#.3g']:
791 pfmt = '%+' + fmt[1:]
792 sfmt = '% ' + fmt[1:]
793 test(fmt, INF, 'inf')
794 test(fmt, -INF, '-inf')
795 test(fmt, NAN, 'nan')
796 test(fmt, -NAN, 'nan')
797 # When asking for a sign, it's always provided. nans are
798 # always positive.
799 test(pfmt, INF, '+inf')
800 test(pfmt, -INF, '-inf')
801 test(pfmt, NAN, '+nan')
802 test(pfmt, -NAN, '+nan')
803 # When using ' ' for a sign code, only infs can be negative.
804 # Others have a space.
805 test(sfmt, INF, ' inf')
806 test(sfmt, -INF, '-inf')
807 test(sfmt, NAN, ' nan')
808 test(sfmt, -NAN, ' nan')
809
Mark Dickinsone6a076d2009-04-18 11:48:33 +0000810
Christian Heimes99170a52007-12-19 02:07:34 +0000811# Beginning with Python 2.6 float has cross platform compatible
Georg Brandl2ee470f2008-07-16 12:55:28 +0000812# ways to create and represent inf and nan
Christian Heimes99170a52007-12-19 02:07:34 +0000813class InfNanTest(unittest.TestCase):
814 def test_inf_from_str(self):
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000815 self.assertTrue(isinf(float("inf")))
816 self.assertTrue(isinf(float("+inf")))
817 self.assertTrue(isinf(float("-inf")))
818 self.assertTrue(isinf(float("infinity")))
819 self.assertTrue(isinf(float("+infinity")))
820 self.assertTrue(isinf(float("-infinity")))
Christian Heimes99170a52007-12-19 02:07:34 +0000821
822 self.assertEqual(repr(float("inf")), "inf")
823 self.assertEqual(repr(float("+inf")), "inf")
824 self.assertEqual(repr(float("-inf")), "-inf")
Georg Brandl2ee470f2008-07-16 12:55:28 +0000825 self.assertEqual(repr(float("infinity")), "inf")
826 self.assertEqual(repr(float("+infinity")), "inf")
827 self.assertEqual(repr(float("-infinity")), "-inf")
Christian Heimes99170a52007-12-19 02:07:34 +0000828
829 self.assertEqual(repr(float("INF")), "inf")
830 self.assertEqual(repr(float("+Inf")), "inf")
831 self.assertEqual(repr(float("-iNF")), "-inf")
Georg Brandl2ee470f2008-07-16 12:55:28 +0000832 self.assertEqual(repr(float("Infinity")), "inf")
833 self.assertEqual(repr(float("+iNfInItY")), "inf")
834 self.assertEqual(repr(float("-INFINITY")), "-inf")
Christian Heimes99170a52007-12-19 02:07:34 +0000835
836 self.assertEqual(str(float("inf")), "inf")
837 self.assertEqual(str(float("+inf")), "inf")
838 self.assertEqual(str(float("-inf")), "-inf")
Georg Brandl2ee470f2008-07-16 12:55:28 +0000839 self.assertEqual(str(float("infinity")), "inf")
840 self.assertEqual(str(float("+infinity")), "inf")
841 self.assertEqual(str(float("-infinity")), "-inf")
Christian Heimes99170a52007-12-19 02:07:34 +0000842
843 self.assertRaises(ValueError, float, "info")
844 self.assertRaises(ValueError, float, "+info")
845 self.assertRaises(ValueError, float, "-info")
846 self.assertRaises(ValueError, float, "in")
847 self.assertRaises(ValueError, float, "+in")
848 self.assertRaises(ValueError, float, "-in")
Georg Brandl2ee470f2008-07-16 12:55:28 +0000849 self.assertRaises(ValueError, float, "infinit")
850 self.assertRaises(ValueError, float, "+Infin")
851 self.assertRaises(ValueError, float, "-INFI")
852 self.assertRaises(ValueError, float, "infinitys")
Christian Heimes99170a52007-12-19 02:07:34 +0000853
Mark Dickinsonbd16edd2009-05-20 22:05:25 +0000854 self.assertRaises(ValueError, float, "++Inf")
855 self.assertRaises(ValueError, float, "-+inf")
856 self.assertRaises(ValueError, float, "+-infinity")
857 self.assertRaises(ValueError, float, "--Infinity")
858
Christian Heimes99170a52007-12-19 02:07:34 +0000859 def test_inf_as_str(self):
860 self.assertEqual(repr(1e300 * 1e300), "inf")
861 self.assertEqual(repr(-1e300 * 1e300), "-inf")
862
863 self.assertEqual(str(1e300 * 1e300), "inf")
864 self.assertEqual(str(-1e300 * 1e300), "-inf")
865
866 def test_nan_from_str(self):
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000867 self.assertTrue(isnan(float("nan")))
868 self.assertTrue(isnan(float("+nan")))
869 self.assertTrue(isnan(float("-nan")))
Christian Heimes99170a52007-12-19 02:07:34 +0000870
871 self.assertEqual(repr(float("nan")), "nan")
872 self.assertEqual(repr(float("+nan")), "nan")
873 self.assertEqual(repr(float("-nan")), "nan")
874
875 self.assertEqual(repr(float("NAN")), "nan")
876 self.assertEqual(repr(float("+NAn")), "nan")
877 self.assertEqual(repr(float("-NaN")), "nan")
878
879 self.assertEqual(str(float("nan")), "nan")
880 self.assertEqual(str(float("+nan")), "nan")
881 self.assertEqual(str(float("-nan")), "nan")
882
883 self.assertRaises(ValueError, float, "nana")
884 self.assertRaises(ValueError, float, "+nana")
885 self.assertRaises(ValueError, float, "-nana")
886 self.assertRaises(ValueError, float, "na")
887 self.assertRaises(ValueError, float, "+na")
888 self.assertRaises(ValueError, float, "-na")
889
Mark Dickinsonbd16edd2009-05-20 22:05:25 +0000890 self.assertRaises(ValueError, float, "++nan")
891 self.assertRaises(ValueError, float, "-+NAN")
892 self.assertRaises(ValueError, float, "+-NaN")
893 self.assertRaises(ValueError, float, "--nAn")
894
Christian Heimes99170a52007-12-19 02:07:34 +0000895 def test_nan_as_str(self):
896 self.assertEqual(repr(1e300 * 1e300 * 0), "nan")
897 self.assertEqual(repr(-1e300 * 1e300 * 0), "nan")
898
899 self.assertEqual(str(1e300 * 1e300 * 0), "nan")
900 self.assertEqual(str(-1e300 * 1e300 * 0), "nan")
Christian Heimes827b35c2007-12-10 22:19:17 +0000901
Mark Dickinsone383e822012-04-29 15:31:56 +0100902 def test_inf_signs(self):
903 self.assertEqual(copysign(1.0, float('inf')), 1.0)
904 self.assertEqual(copysign(1.0, float('-inf')), -1.0)
905
906 @unittest.skipUnless(getattr(sys, 'float_repr_style', '') == 'short',
907 "applies only when using short float repr style")
908 def test_nan_signs(self):
909 # When using the dtoa.c code, the sign of float('nan') should
910 # be predictable.
911 self.assertEqual(copysign(1.0, float('nan')), 1.0)
912 self.assertEqual(copysign(1.0, float('-nan')), -1.0)
913
914
Mark Dickinson65fe25e2008-07-16 11:30:51 +0000915fromHex = float.fromhex
916toHex = float.hex
917class HexFloatTestCase(unittest.TestCase):
918 MAX = fromHex('0x.fffffffffffff8p+1024') # max normal
919 MIN = fromHex('0x1p-1022') # min normal
920 TINY = fromHex('0x0.0000000000001p-1022') # min subnormal
921 EPS = fromHex('0x0.0000000000001p0') # diff between 1.0 and next float up
922
923 def identical(self, x, y):
924 # check that floats x and y are identical, or that both
925 # are NaNs
926 if isnan(x) or isnan(y):
927 if isnan(x) == isnan(y):
928 return
929 elif x == y and (x != 0.0 or copysign(1.0, x) == copysign(1.0, y)):
930 return
931 self.fail('%r not identical to %r' % (x, y))
932
933 def test_ends(self):
Mark Dickinson38bbc482008-07-16 11:32:23 +0000934 self.identical(self.MIN, ldexp(1.0, -1022))
935 self.identical(self.TINY, ldexp(1.0, -1074))
936 self.identical(self.EPS, ldexp(1.0, -52))
937 self.identical(self.MAX, 2.*(ldexp(1.0, 1023) - ldexp(1.0, 970)))
Mark Dickinson65fe25e2008-07-16 11:30:51 +0000938
939 def test_invalid_inputs(self):
940 invalid_inputs = [
941 'infi', # misspelt infinities and nans
942 '-Infinit',
943 '++inf',
944 '-+Inf',
945 '--nan',
946 '+-NaN',
947 'snan',
948 'NaNs',
949 'nna',
Mark Dickinsond1ec8b22009-05-11 15:45:15 +0000950 'an',
951 'nf',
952 'nfinity',
953 'inity',
954 'iinity',
Mark Dickinson65fe25e2008-07-16 11:30:51 +0000955 '0xnan',
956 '',
957 ' ',
958 'x1.0p0',
959 '0xX1.0p0',
960 '+ 0x1.0p0', # internal whitespace
961 '- 0x1.0p0',
962 '0 x1.0p0',
963 '0x 1.0p0',
964 '0x1 2.0p0',
965 '+0x1 .0p0',
966 '0x1. 0p0',
967 '-0x1.0 1p0',
968 '-0x1.0 p0',
969 '+0x1.0p +0',
970 '0x1.0p -0',
971 '0x1.0p 0',
972 '+0x1.0p+ 0',
973 '-0x1.0p- 0',
974 '++0x1.0p-0', # double signs
975 '--0x1.0p0',
976 '+-0x1.0p+0',
977 '-+0x1.0p0',
978 '0x1.0p++0',
979 '+0x1.0p+-0',
980 '-0x1.0p-+0',
981 '0x1.0p--0',
982 '0x1.0.p0',
983 '0x.p0', # no hex digits before or after point
984 '0x1,p0', # wrong decimal point character
985 '0x1pa',
986 '0x1p\uff10', # fullwidth Unicode digits
987 '\uff10x1p0',
988 '0x\uff11p0',
989 '0x1.\uff10p0',
990 '0x1p0 \n 0x2p0',
991 '0x1p0\0 0x1p0', # embedded null byte is not end of string
992 ]
993 for x in invalid_inputs:
Mark Dickinson589b7952008-08-21 20:05:56 +0000994 try:
995 result = fromHex(x)
996 except ValueError:
997 pass
998 else:
999 self.fail('Expected float.fromhex(%r) to raise ValueError; '
1000 'got %r instead' % (x, result))
Mark Dickinson65fe25e2008-07-16 11:30:51 +00001001
1002
Mark Dickinsond1ec8b22009-05-11 15:45:15 +00001003 def test_whitespace(self):
1004 value_pairs = [
1005 ('inf', INF),
1006 ('-Infinity', -INF),
1007 ('nan', NAN),
1008 ('1.0', 1.0),
1009 ('-0x.2', -0.125),
1010 ('-0.0', -0.0)
1011 ]
1012 whitespace = [
1013 '',
1014 ' ',
1015 '\t',
1016 '\n',
1017 '\n \t',
1018 '\f',
1019 '\v',
1020 '\r'
1021 ]
1022 for inp, expected in value_pairs:
1023 for lead in whitespace:
1024 for trail in whitespace:
1025 got = fromHex(lead + inp + trail)
1026 self.identical(got, expected)
1027
1028
Mark Dickinson65fe25e2008-07-16 11:30:51 +00001029 def test_from_hex(self):
1030 MIN = self.MIN;
1031 MAX = self.MAX;
1032 TINY = self.TINY;
1033 EPS = self.EPS;
1034
1035 # two spellings of infinity, with optional signs; case-insensitive
1036 self.identical(fromHex('inf'), INF)
1037 self.identical(fromHex('+Inf'), INF)
1038 self.identical(fromHex('-INF'), -INF)
1039 self.identical(fromHex('iNf'), INF)
1040 self.identical(fromHex('Infinity'), INF)
1041 self.identical(fromHex('+INFINITY'), INF)
1042 self.identical(fromHex('-infinity'), -INF)
1043 self.identical(fromHex('-iNFiNitY'), -INF)
1044
1045 # nans with optional sign; case insensitive
1046 self.identical(fromHex('nan'), NAN)
1047 self.identical(fromHex('+NaN'), NAN)
1048 self.identical(fromHex('-NaN'), NAN)
1049 self.identical(fromHex('-nAN'), NAN)
1050
1051 # variations in input format
1052 self.identical(fromHex('1'), 1.0)
1053 self.identical(fromHex('+1'), 1.0)
1054 self.identical(fromHex('1.'), 1.0)
1055 self.identical(fromHex('1.0'), 1.0)
1056 self.identical(fromHex('1.0p0'), 1.0)
1057 self.identical(fromHex('01'), 1.0)
1058 self.identical(fromHex('01.'), 1.0)
1059 self.identical(fromHex('0x1'), 1.0)
1060 self.identical(fromHex('0x1.'), 1.0)
1061 self.identical(fromHex('0x1.0'), 1.0)
1062 self.identical(fromHex('+0x1.0'), 1.0)
1063 self.identical(fromHex('0x1p0'), 1.0)
1064 self.identical(fromHex('0X1p0'), 1.0)
1065 self.identical(fromHex('0X1P0'), 1.0)
1066 self.identical(fromHex('0x1P0'), 1.0)
1067 self.identical(fromHex('0x1.p0'), 1.0)
1068 self.identical(fromHex('0x1.0p0'), 1.0)
1069 self.identical(fromHex('0x.1p4'), 1.0)
1070 self.identical(fromHex('0x.1p04'), 1.0)
1071 self.identical(fromHex('0x.1p004'), 1.0)
1072 self.identical(fromHex('0x1p+0'), 1.0)
1073 self.identical(fromHex('0x1P-0'), 1.0)
1074 self.identical(fromHex('+0x1p0'), 1.0)
1075 self.identical(fromHex('0x01p0'), 1.0)
1076 self.identical(fromHex('0x1p00'), 1.0)
1077 self.identical(fromHex(' 0x1p0 '), 1.0)
1078 self.identical(fromHex('\n 0x1p0'), 1.0)
1079 self.identical(fromHex('0x1p0 \t'), 1.0)
1080 self.identical(fromHex('0xap0'), 10.0)
1081 self.identical(fromHex('0xAp0'), 10.0)
1082 self.identical(fromHex('0xaP0'), 10.0)
1083 self.identical(fromHex('0xAP0'), 10.0)
1084 self.identical(fromHex('0xbep0'), 190.0)
1085 self.identical(fromHex('0xBep0'), 190.0)
1086 self.identical(fromHex('0xbEp0'), 190.0)
1087 self.identical(fromHex('0XBE0P-4'), 190.0)
1088 self.identical(fromHex('0xBEp0'), 190.0)
1089 self.identical(fromHex('0xB.Ep4'), 190.0)
1090 self.identical(fromHex('0x.BEp8'), 190.0)
1091 self.identical(fromHex('0x.0BEp12'), 190.0)
1092
1093 # moving the point around
1094 pi = fromHex('0x1.921fb54442d18p1')
1095 self.identical(fromHex('0x.006487ed5110b46p11'), pi)
1096 self.identical(fromHex('0x.00c90fdaa22168cp10'), pi)
1097 self.identical(fromHex('0x.01921fb54442d18p9'), pi)
1098 self.identical(fromHex('0x.03243f6a8885a3p8'), pi)
1099 self.identical(fromHex('0x.06487ed5110b46p7'), pi)
1100 self.identical(fromHex('0x.0c90fdaa22168cp6'), pi)
1101 self.identical(fromHex('0x.1921fb54442d18p5'), pi)
1102 self.identical(fromHex('0x.3243f6a8885a3p4'), pi)
1103 self.identical(fromHex('0x.6487ed5110b46p3'), pi)
1104 self.identical(fromHex('0x.c90fdaa22168cp2'), pi)
1105 self.identical(fromHex('0x1.921fb54442d18p1'), pi)
1106 self.identical(fromHex('0x3.243f6a8885a3p0'), pi)
1107 self.identical(fromHex('0x6.487ed5110b46p-1'), pi)
1108 self.identical(fromHex('0xc.90fdaa22168cp-2'), pi)
1109 self.identical(fromHex('0x19.21fb54442d18p-3'), pi)
1110 self.identical(fromHex('0x32.43f6a8885a3p-4'), pi)
1111 self.identical(fromHex('0x64.87ed5110b46p-5'), pi)
1112 self.identical(fromHex('0xc9.0fdaa22168cp-6'), pi)
1113 self.identical(fromHex('0x192.1fb54442d18p-7'), pi)
1114 self.identical(fromHex('0x324.3f6a8885a3p-8'), pi)
1115 self.identical(fromHex('0x648.7ed5110b46p-9'), pi)
1116 self.identical(fromHex('0xc90.fdaa22168cp-10'), pi)
1117 self.identical(fromHex('0x1921.fb54442d18p-11'), pi)
1118 # ...
1119 self.identical(fromHex('0x1921fb54442d1.8p-47'), pi)
1120 self.identical(fromHex('0x3243f6a8885a3p-48'), pi)
1121 self.identical(fromHex('0x6487ed5110b46p-49'), pi)
1122 self.identical(fromHex('0xc90fdaa22168cp-50'), pi)
1123 self.identical(fromHex('0x1921fb54442d18p-51'), pi)
1124 self.identical(fromHex('0x3243f6a8885a30p-52'), pi)
1125 self.identical(fromHex('0x6487ed5110b460p-53'), pi)
1126 self.identical(fromHex('0xc90fdaa22168c0p-54'), pi)
1127 self.identical(fromHex('0x1921fb54442d180p-55'), pi)
1128
1129
1130 # results that should overflow...
1131 self.assertRaises(OverflowError, fromHex, '-0x1p1024')
1132 self.assertRaises(OverflowError, fromHex, '0x1p+1025')
1133 self.assertRaises(OverflowError, fromHex, '+0X1p1030')
1134 self.assertRaises(OverflowError, fromHex, '-0x1p+1100')
1135 self.assertRaises(OverflowError, fromHex, '0X1p123456789123456789')
1136 self.assertRaises(OverflowError, fromHex, '+0X.8p+1025')
1137 self.assertRaises(OverflowError, fromHex, '+0x0.8p1025')
1138 self.assertRaises(OverflowError, fromHex, '-0x0.4p1026')
1139 self.assertRaises(OverflowError, fromHex, '0X2p+1023')
1140 self.assertRaises(OverflowError, fromHex, '0x2.p1023')
1141 self.assertRaises(OverflowError, fromHex, '-0x2.0p+1023')
1142 self.assertRaises(OverflowError, fromHex, '+0X4p+1022')
1143 self.assertRaises(OverflowError, fromHex, '0x1.ffffffffffffffp+1023')
1144 self.assertRaises(OverflowError, fromHex, '-0X1.fffffffffffff9p1023')
1145 self.assertRaises(OverflowError, fromHex, '0X1.fffffffffffff8p1023')
1146 self.assertRaises(OverflowError, fromHex, '+0x3.fffffffffffffp1022')
1147 self.assertRaises(OverflowError, fromHex, '0x3fffffffffffffp+970')
1148 self.assertRaises(OverflowError, fromHex, '0x10000000000000000p960')
1149 self.assertRaises(OverflowError, fromHex, '-0Xffffffffffffffffp960')
1150
1151 # ...and those that round to +-max float
1152 self.identical(fromHex('+0x1.fffffffffffffp+1023'), MAX)
1153 self.identical(fromHex('-0X1.fffffffffffff7p1023'), -MAX)
1154 self.identical(fromHex('0X1.fffffffffffff7fffffffffffffp1023'), MAX)
1155
1156 # zeros
1157 self.identical(fromHex('0x0p0'), 0.0)
1158 self.identical(fromHex('0x0p1000'), 0.0)
1159 self.identical(fromHex('-0x0p1023'), -0.0)
1160 self.identical(fromHex('0X0p1024'), 0.0)
1161 self.identical(fromHex('-0x0p1025'), -0.0)
1162 self.identical(fromHex('0X0p2000'), 0.0)
1163 self.identical(fromHex('0x0p123456789123456789'), 0.0)
1164 self.identical(fromHex('-0X0p-0'), -0.0)
1165 self.identical(fromHex('-0X0p-1000'), -0.0)
1166 self.identical(fromHex('0x0p-1023'), 0.0)
1167 self.identical(fromHex('-0X0p-1024'), -0.0)
1168 self.identical(fromHex('-0x0p-1025'), -0.0)
1169 self.identical(fromHex('-0x0p-1072'), -0.0)
1170 self.identical(fromHex('0X0p-1073'), 0.0)
1171 self.identical(fromHex('-0x0p-1074'), -0.0)
1172 self.identical(fromHex('0x0p-1075'), 0.0)
1173 self.identical(fromHex('0X0p-1076'), 0.0)
1174 self.identical(fromHex('-0X0p-2000'), -0.0)
1175 self.identical(fromHex('-0x0p-123456789123456789'), -0.0)
1176
1177 # values that should underflow to 0
1178 self.identical(fromHex('0X1p-1075'), 0.0)
1179 self.identical(fromHex('-0X1p-1075'), -0.0)
1180 self.identical(fromHex('-0x1p-123456789123456789'), -0.0)
1181 self.identical(fromHex('0x1.00000000000000001p-1075'), TINY)
1182 self.identical(fromHex('-0x1.1p-1075'), -TINY)
1183 self.identical(fromHex('0x1.fffffffffffffffffp-1075'), TINY)
1184
1185 # check round-half-even is working correctly near 0 ...
1186 self.identical(fromHex('0x1p-1076'), 0.0)
1187 self.identical(fromHex('0X2p-1076'), 0.0)
1188 self.identical(fromHex('0X3p-1076'), TINY)
1189 self.identical(fromHex('0x4p-1076'), TINY)
1190 self.identical(fromHex('0X5p-1076'), TINY)
1191 self.identical(fromHex('0X6p-1076'), 2*TINY)
1192 self.identical(fromHex('0x7p-1076'), 2*TINY)
1193 self.identical(fromHex('0X8p-1076'), 2*TINY)
1194 self.identical(fromHex('0X9p-1076'), 2*TINY)
1195 self.identical(fromHex('0xap-1076'), 2*TINY)
1196 self.identical(fromHex('0Xbp-1076'), 3*TINY)
1197 self.identical(fromHex('0xcp-1076'), 3*TINY)
1198 self.identical(fromHex('0Xdp-1076'), 3*TINY)
1199 self.identical(fromHex('0Xep-1076'), 4*TINY)
1200 self.identical(fromHex('0xfp-1076'), 4*TINY)
1201 self.identical(fromHex('0x10p-1076'), 4*TINY)
1202 self.identical(fromHex('-0x1p-1076'), -0.0)
1203 self.identical(fromHex('-0X2p-1076'), -0.0)
1204 self.identical(fromHex('-0x3p-1076'), -TINY)
1205 self.identical(fromHex('-0X4p-1076'), -TINY)
1206 self.identical(fromHex('-0x5p-1076'), -TINY)
1207 self.identical(fromHex('-0x6p-1076'), -2*TINY)
1208 self.identical(fromHex('-0X7p-1076'), -2*TINY)
1209 self.identical(fromHex('-0X8p-1076'), -2*TINY)
1210 self.identical(fromHex('-0X9p-1076'), -2*TINY)
1211 self.identical(fromHex('-0Xap-1076'), -2*TINY)
1212 self.identical(fromHex('-0xbp-1076'), -3*TINY)
1213 self.identical(fromHex('-0xcp-1076'), -3*TINY)
1214 self.identical(fromHex('-0Xdp-1076'), -3*TINY)
1215 self.identical(fromHex('-0xep-1076'), -4*TINY)
1216 self.identical(fromHex('-0Xfp-1076'), -4*TINY)
1217 self.identical(fromHex('-0X10p-1076'), -4*TINY)
1218
1219 # ... and near MIN ...
1220 self.identical(fromHex('0x0.ffffffffffffd6p-1022'), MIN-3*TINY)
1221 self.identical(fromHex('0x0.ffffffffffffd8p-1022'), MIN-2*TINY)
1222 self.identical(fromHex('0x0.ffffffffffffdap-1022'), MIN-2*TINY)
1223 self.identical(fromHex('0x0.ffffffffffffdcp-1022'), MIN-2*TINY)
1224 self.identical(fromHex('0x0.ffffffffffffdep-1022'), MIN-2*TINY)
1225 self.identical(fromHex('0x0.ffffffffffffe0p-1022'), MIN-2*TINY)
1226 self.identical(fromHex('0x0.ffffffffffffe2p-1022'), MIN-2*TINY)
1227 self.identical(fromHex('0x0.ffffffffffffe4p-1022'), MIN-2*TINY)
1228 self.identical(fromHex('0x0.ffffffffffffe6p-1022'), MIN-2*TINY)
1229 self.identical(fromHex('0x0.ffffffffffffe8p-1022'), MIN-2*TINY)
1230 self.identical(fromHex('0x0.ffffffffffffeap-1022'), MIN-TINY)
1231 self.identical(fromHex('0x0.ffffffffffffecp-1022'), MIN-TINY)
1232 self.identical(fromHex('0x0.ffffffffffffeep-1022'), MIN-TINY)
1233 self.identical(fromHex('0x0.fffffffffffff0p-1022'), MIN-TINY)
1234 self.identical(fromHex('0x0.fffffffffffff2p-1022'), MIN-TINY)
1235 self.identical(fromHex('0x0.fffffffffffff4p-1022'), MIN-TINY)
1236 self.identical(fromHex('0x0.fffffffffffff6p-1022'), MIN-TINY)
1237 self.identical(fromHex('0x0.fffffffffffff8p-1022'), MIN)
1238 self.identical(fromHex('0x0.fffffffffffffap-1022'), MIN)
1239 self.identical(fromHex('0x0.fffffffffffffcp-1022'), MIN)
1240 self.identical(fromHex('0x0.fffffffffffffep-1022'), MIN)
1241 self.identical(fromHex('0x1.00000000000000p-1022'), MIN)
1242 self.identical(fromHex('0x1.00000000000002p-1022'), MIN)
1243 self.identical(fromHex('0x1.00000000000004p-1022'), MIN)
1244 self.identical(fromHex('0x1.00000000000006p-1022'), MIN)
1245 self.identical(fromHex('0x1.00000000000008p-1022'), MIN)
1246 self.identical(fromHex('0x1.0000000000000ap-1022'), MIN+TINY)
1247 self.identical(fromHex('0x1.0000000000000cp-1022'), MIN+TINY)
1248 self.identical(fromHex('0x1.0000000000000ep-1022'), MIN+TINY)
1249 self.identical(fromHex('0x1.00000000000010p-1022'), MIN+TINY)
1250 self.identical(fromHex('0x1.00000000000012p-1022'), MIN+TINY)
1251 self.identical(fromHex('0x1.00000000000014p-1022'), MIN+TINY)
1252 self.identical(fromHex('0x1.00000000000016p-1022'), MIN+TINY)
1253 self.identical(fromHex('0x1.00000000000018p-1022'), MIN+2*TINY)
1254
1255 # ... and near 1.0.
1256 self.identical(fromHex('0x0.fffffffffffff0p0'), 1.0-EPS)
1257 self.identical(fromHex('0x0.fffffffffffff1p0'), 1.0-EPS)
1258 self.identical(fromHex('0X0.fffffffffffff2p0'), 1.0-EPS)
1259 self.identical(fromHex('0x0.fffffffffffff3p0'), 1.0-EPS)
1260 self.identical(fromHex('0X0.fffffffffffff4p0'), 1.0-EPS)
1261 self.identical(fromHex('0X0.fffffffffffff5p0'), 1.0-EPS/2)
1262 self.identical(fromHex('0X0.fffffffffffff6p0'), 1.0-EPS/2)
1263 self.identical(fromHex('0x0.fffffffffffff7p0'), 1.0-EPS/2)
1264 self.identical(fromHex('0x0.fffffffffffff8p0'), 1.0-EPS/2)
1265 self.identical(fromHex('0X0.fffffffffffff9p0'), 1.0-EPS/2)
1266 self.identical(fromHex('0X0.fffffffffffffap0'), 1.0-EPS/2)
1267 self.identical(fromHex('0x0.fffffffffffffbp0'), 1.0-EPS/2)
1268 self.identical(fromHex('0X0.fffffffffffffcp0'), 1.0)
1269 self.identical(fromHex('0x0.fffffffffffffdp0'), 1.0)
1270 self.identical(fromHex('0X0.fffffffffffffep0'), 1.0)
1271 self.identical(fromHex('0x0.ffffffffffffffp0'), 1.0)
1272 self.identical(fromHex('0X1.00000000000000p0'), 1.0)
1273 self.identical(fromHex('0X1.00000000000001p0'), 1.0)
1274 self.identical(fromHex('0x1.00000000000002p0'), 1.0)
1275 self.identical(fromHex('0X1.00000000000003p0'), 1.0)
1276 self.identical(fromHex('0x1.00000000000004p0'), 1.0)
1277 self.identical(fromHex('0X1.00000000000005p0'), 1.0)
1278 self.identical(fromHex('0X1.00000000000006p0'), 1.0)
1279 self.identical(fromHex('0X1.00000000000007p0'), 1.0)
1280 self.identical(fromHex('0x1.00000000000007ffffffffffffffffffffp0'),
1281 1.0)
1282 self.identical(fromHex('0x1.00000000000008p0'), 1.0)
1283 self.identical(fromHex('0x1.00000000000008000000000000000001p0'),
1284 1+EPS)
1285 self.identical(fromHex('0X1.00000000000009p0'), 1.0+EPS)
1286 self.identical(fromHex('0x1.0000000000000ap0'), 1.0+EPS)
1287 self.identical(fromHex('0x1.0000000000000bp0'), 1.0+EPS)
1288 self.identical(fromHex('0X1.0000000000000cp0'), 1.0+EPS)
1289 self.identical(fromHex('0x1.0000000000000dp0'), 1.0+EPS)
1290 self.identical(fromHex('0x1.0000000000000ep0'), 1.0+EPS)
1291 self.identical(fromHex('0X1.0000000000000fp0'), 1.0+EPS)
1292 self.identical(fromHex('0x1.00000000000010p0'), 1.0+EPS)
1293 self.identical(fromHex('0X1.00000000000011p0'), 1.0+EPS)
1294 self.identical(fromHex('0x1.00000000000012p0'), 1.0+EPS)
1295 self.identical(fromHex('0X1.00000000000013p0'), 1.0+EPS)
1296 self.identical(fromHex('0X1.00000000000014p0'), 1.0+EPS)
1297 self.identical(fromHex('0x1.00000000000015p0'), 1.0+EPS)
1298 self.identical(fromHex('0x1.00000000000016p0'), 1.0+EPS)
1299 self.identical(fromHex('0X1.00000000000017p0'), 1.0+EPS)
1300 self.identical(fromHex('0x1.00000000000017ffffffffffffffffffffp0'),
1301 1.0+EPS)
1302 self.identical(fromHex('0x1.00000000000018p0'), 1.0+2*EPS)
1303 self.identical(fromHex('0X1.00000000000018000000000000000001p0'),
1304 1.0+2*EPS)
1305 self.identical(fromHex('0x1.00000000000019p0'), 1.0+2*EPS)
1306 self.identical(fromHex('0X1.0000000000001ap0'), 1.0+2*EPS)
1307 self.identical(fromHex('0X1.0000000000001bp0'), 1.0+2*EPS)
1308 self.identical(fromHex('0x1.0000000000001cp0'), 1.0+2*EPS)
1309 self.identical(fromHex('0x1.0000000000001dp0'), 1.0+2*EPS)
1310 self.identical(fromHex('0x1.0000000000001ep0'), 1.0+2*EPS)
1311 self.identical(fromHex('0X1.0000000000001fp0'), 1.0+2*EPS)
1312 self.identical(fromHex('0x1.00000000000020p0'), 1.0+2*EPS)
1313
1314 def test_roundtrip(self):
1315 def roundtrip(x):
1316 return fromHex(toHex(x))
1317
1318 for x in [NAN, INF, self.MAX, self.MIN, self.MIN-self.TINY, self.TINY, 0.0]:
1319 self.identical(x, roundtrip(x))
1320 self.identical(-x, roundtrip(-x))
1321
1322 # fromHex(toHex(x)) should exactly recover x, for any non-NaN float x.
1323 import random
1324 for i in range(10000):
1325 e = random.randrange(-1200, 1200)
1326 m = random.random()
1327 s = random.choice([1.0, -1.0])
1328 try:
1329 x = s*ldexp(m, e)
1330 except OverflowError:
1331 pass
1332 else:
1333 self.identical(x, fromHex(toHex(x)))
1334
Christian Heimes53876d92008-04-19 00:31:39 +00001335
Michael W. Hudsonba283e22005-05-27 15:23:20 +00001336def test_main():
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001337 support.run_unittest(
Amaury Forgeot d'Arc7e958d12008-09-06 21:03:22 +00001338 GeneralFloatCases,
Michael W. Hudsonba283e22005-05-27 15:23:20 +00001339 FormatFunctionsTestCase,
1340 UnknownFormatTestCase,
Eric Smith8c663262007-08-25 02:26:07 +00001341 IEEEFormatTestCase,
Christian Heimes827b35c2007-12-10 22:19:17 +00001342 FormatTestCase,
Christian Heimes99170a52007-12-19 02:07:34 +00001343 ReprTestCase,
Mark Dickinsone6a076d2009-04-18 11:48:33 +00001344 RoundTestCase,
Christian Heimes99170a52007-12-19 02:07:34 +00001345 InfNanTest,
Mark Dickinson65fe25e2008-07-16 11:30:51 +00001346 HexFloatTestCase,
Christian Heimesb76922a2007-12-11 01:06:40 +00001347 )
Michael W. Hudsonba283e22005-05-27 15:23:20 +00001348
1349if __name__ == '__main__':
1350 test_main()