blob: cb1f6db8fc76279a1954af4b233f37c940ed5f79 [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
Serhiy Storchaka15095802015-11-25 15:47:01 +020028class FloatSubclass(float):
29 pass
30
31class OtherFloatSubclass(float):
32 pass
33
Christian Heimes81ee3ef2008-05-04 22:42:01 +000034class GeneralFloatCases(unittest.TestCase):
35
36 def test_float(self):
37 self.assertEqual(float(3.14), 3.14)
38 self.assertEqual(float(314), 314.0)
39 self.assertEqual(float(" 3.14 "), 3.14)
40 self.assertRaises(ValueError, float, " 0x3.1 ")
41 self.assertRaises(ValueError, float, " -0x3.p-1 ")
42 self.assertRaises(ValueError, float, " +0x3.p-1 ")
43 self.assertRaises(ValueError, float, "++3.14")
44 self.assertRaises(ValueError, float, "+-3.14")
45 self.assertRaises(ValueError, float, "-+3.14")
46 self.assertRaises(ValueError, float, "--3.14")
Eric Smith0923d1d2009-04-16 20:16:10 +000047 self.assertRaises(ValueError, float, ".nan")
48 self.assertRaises(ValueError, float, "+.inf")
49 self.assertRaises(ValueError, float, ".")
50 self.assertRaises(ValueError, float, "-.")
Alexander Belopolsky942af5a2010-12-04 03:38:46 +000051 self.assertRaises(TypeError, float, {})
Ezio Melottia5b95992013-11-07 19:18:34 +020052 self.assertRaisesRegex(TypeError, "not 'dict'", float, {})
Alexander Belopolsky942af5a2010-12-04 03:38:46 +000053 # Lone surrogate
54 self.assertRaises(UnicodeEncodeError, float, '\uD8F0')
Mark Dickinsonc2d86892010-02-12 21:18:34 +000055 # check that we don't accept alternate exponent markers
56 self.assertRaises(ValueError, float, "-1.7d29")
57 self.assertRaises(ValueError, float, "3D-14")
Alexander Belopolsky942af5a2010-12-04 03:38:46 +000058 self.assertEqual(float(" \u0663.\u0661\u0664 "), 3.14)
59 self.assertEqual(float("\N{EM SPACE}3.14\N{EN SPACE}"), 3.14)
Mark Dickinsona9023be2009-10-27 22:12:20 +000060 # extra long strings should not be a problem
61 float(b'.' + b'1'*1000)
62 float('.' + '1'*1000)
Christian Heimes81ee3ef2008-05-04 22:42:01 +000063
Martin Pantereeb896c2015-11-07 02:32:21 +000064 def test_non_numeric_input_types(self):
65 # Test possible non-numeric types for the argument x, including
66 # subclasses of the explicitly documented accepted types.
67 class CustomStr(str): pass
68 class CustomBytes(bytes): pass
69 class CustomByteArray(bytearray): pass
70
71 factories = [
72 bytes,
73 bytearray,
74 lambda b: CustomStr(b.decode()),
75 CustomBytes,
76 CustomByteArray,
77 memoryview,
78 ]
79 try:
80 from array import array
81 except ImportError:
82 pass
83 else:
84 factories.append(lambda b: array('B', b))
85
86 for f in factories:
87 x = f(b" 3.14 ")
88 with self.subTest(type(x)):
89 self.assertEqual(float(x), 3.14)
90 with self.assertRaisesRegex(ValueError, "could not convert"):
91 float(f(b'A' * 0x10))
92
93 def test_float_memoryview(self):
94 self.assertEqual(float(memoryview(b'12.3')[1:4]), 2.3)
95 self.assertEqual(float(memoryview(b'12.3\x00')[1:4]), 2.3)
96 self.assertEqual(float(memoryview(b'12.3 ')[1:4]), 2.3)
97 self.assertEqual(float(memoryview(b'12.3A')[1:4]), 2.3)
98 self.assertEqual(float(memoryview(b'12.34')[1:4]), 2.3)
99
Alexander Belopolsky942af5a2010-12-04 03:38:46 +0000100 def test_error_message(self):
101 testlist = ('\xbd', '123\xbd', ' 123 456 ')
102 for s in testlist:
103 try:
104 float(s)
105 except ValueError as e:
106 self.assertIn(s.strip(), e.args[0])
107 else:
108 self.fail("Expected int(%r) to raise a ValueError", s)
109
110
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000111 @support.run_with_locale('LC_NUMERIC', 'fr_FR', 'de_DE')
Christian Heimes81ee3ef2008-05-04 22:42:01 +0000112 def test_float_with_comma(self):
113 # set locale to something that doesn't use '.' for the decimal point
114 # float must not accept the locale specific decimal point but
Ezio Melotti13925002011-03-16 11:05:33 +0200115 # it still has to accept the normal python syntax
Christian Heimes81ee3ef2008-05-04 22:42:01 +0000116 import locale
117 if not locale.localeconv()['decimal_point'] == ',':
Zachary Ware9fe6d862013-12-08 00:20:35 -0600118 self.skipTest('decimal_point is not ","')
Christian Heimes81ee3ef2008-05-04 22:42:01 +0000119
120 self.assertEqual(float(" 3.14 "), 3.14)
121 self.assertEqual(float("+3.14 "), 3.14)
122 self.assertEqual(float("-3.14 "), -3.14)
123 self.assertEqual(float(".14 "), .14)
124 self.assertEqual(float("3. "), 3.0)
125 self.assertEqual(float("3.e3 "), 3000.0)
126 self.assertEqual(float("3.2e3 "), 3200.0)
127 self.assertEqual(float("2.5e-1 "), 0.25)
128 self.assertEqual(float("5e-1"), 0.5)
129 self.assertRaises(ValueError, float, " 3,14 ")
130 self.assertRaises(ValueError, float, " +3,14 ")
131 self.assertRaises(ValueError, float, " -3,14 ")
132 self.assertRaises(ValueError, float, " 0x3.1 ")
133 self.assertRaises(ValueError, float, " -0x3.p-1 ")
134 self.assertRaises(ValueError, float, " +0x3.p-1 ")
135 self.assertEqual(float(" 25.e-1 "), 2.5)
Eli Bendersky67ebabd2011-02-25 10:14:17 +0000136 self.assertAlmostEqual(float(" .25e-1 "), .025)
Christian Heimes81ee3ef2008-05-04 22:42:01 +0000137
138 def test_floatconversion(self):
139 # Make sure that calls to __float__() work properly
Christian Heimes81ee3ef2008-05-04 22:42:01 +0000140 class Foo1(object):
141 def __float__(self):
142 return 42.
143
144 class Foo2(float):
145 def __float__(self):
146 return 42.
147
148 class Foo3(float):
149 def __new__(cls, value=0.):
150 return float.__new__(cls, 2*value)
151
152 def __float__(self):
153 return self
154
155 class Foo4(float):
156 def __float__(self):
157 return 42
158
Benjamin Peterson2808d3c2009-04-15 21:34:27 +0000159 # Issue 5759: __float__ not called on str subclasses (though it is on
160 # unicode subclasses).
161 class FooStr(str):
162 def __float__(self):
163 return float(str(self)) + 1
164
Christian Heimes81ee3ef2008-05-04 22:42:01 +0000165 self.assertAlmostEqual(float(Foo1()), 42.)
166 self.assertAlmostEqual(float(Foo2()), 42.)
167 self.assertAlmostEqual(float(Foo3(21)), 42.)
168 self.assertRaises(TypeError, float, Foo4(42))
Benjamin Peterson2808d3c2009-04-15 21:34:27 +0000169 self.assertAlmostEqual(float(FooStr('8')), 9.)
Christian Heimes81ee3ef2008-05-04 22:42:01 +0000170
Benjamin Petersona9157232015-03-06 09:08:44 -0500171 class Foo5:
172 def __float__(self):
173 return ""
174 self.assertRaises(TypeError, time.sleep, Foo5())
175
Serhiy Storchaka15095802015-11-25 15:47:01 +0200176 # Issue #24731
177 class F:
178 def __float__(self):
179 return OtherFloatSubclass(42.)
180 self.assertAlmostEqual(float(F()), 42.)
181 self.assertIs(type(float(F())), OtherFloatSubclass)
182 self.assertAlmostEqual(FloatSubclass(F()), 42.)
183 self.assertIs(type(FloatSubclass(F())), FloatSubclass)
184
Benjamin Petersonb3b8ba62011-10-28 19:42:48 -0400185 def test_is_integer(self):
186 self.assertFalse((1.1).is_integer())
187 self.assertTrue((1.).is_integer())
188 self.assertFalse(float("nan").is_integer())
189 self.assertFalse(float("inf").is_integer())
190
Christian Heimes81ee3ef2008-05-04 22:42:01 +0000191 def test_floatasratio(self):
192 for f, ratio in [
193 (0.875, (7, 8)),
194 (-0.875, (-7, 8)),
195 (0.0, (0, 1)),
196 (11.5, (23, 2)),
197 ]:
198 self.assertEqual(f.as_integer_ratio(), ratio)
199
200 for i in range(10000):
201 f = random.random()
202 f *= 10 ** random.randint(-100, 100)
203 n, d = f.as_integer_ratio()
204 self.assertEqual(float(n).__truediv__(d), f)
205
206 R = fractions.Fraction
207 self.assertEqual(R(0, 1),
208 R(*float(0.0).as_integer_ratio()))
209 self.assertEqual(R(5, 2),
210 R(*float(2.5).as_integer_ratio()))
211 self.assertEqual(R(1, 2),
212 R(*float(0.5).as_integer_ratio()))
213 self.assertEqual(R(4728779608739021, 2251799813685248),
214 R(*float(2.1).as_integer_ratio()))
215 self.assertEqual(R(-4728779608739021, 2251799813685248),
216 R(*float(-2.1).as_integer_ratio()))
217 self.assertEqual(R(-2100, 1),
218 R(*float(-2100.0).as_integer_ratio()))
219
220 self.assertRaises(OverflowError, float('inf').as_integer_ratio)
221 self.assertRaises(OverflowError, float('-inf').as_integer_ratio)
222 self.assertRaises(ValueError, float('nan').as_integer_ratio)
223
Mark Dickinson4a1f5932008-11-12 23:23:36 +0000224 def test_float_containment(self):
225 floats = (INF, -INF, 0.0, 1.0, NAN)
226 for f in floats:
Benjamin Peterson577473f2010-01-19 00:09:57 +0000227 self.assertIn(f, [f])
Benjamin Peterson577473f2010-01-19 00:09:57 +0000228 self.assertIn(f, (f,))
Benjamin Peterson577473f2010-01-19 00:09:57 +0000229 self.assertIn(f, {f})
Benjamin Peterson577473f2010-01-19 00:09:57 +0000230 self.assertIn(f, {f: None})
Mark Dickinson4a1f5932008-11-12 23:23:36 +0000231 self.assertEqual([f].count(f), 1, "[].count('%r') != 1" % f)
Benjamin Peterson577473f2010-01-19 00:09:57 +0000232 self.assertIn(f, floats)
Mark Dickinson4a1f5932008-11-12 23:23:36 +0000233
234 for f in floats:
235 # nonidentical containers, same type, same contents
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000236 self.assertTrue([f] == [f], "[%r] != [%r]" % (f, f))
237 self.assertTrue((f,) == (f,), "(%r,) != (%r,)" % (f, f))
238 self.assertTrue({f} == {f}, "{%r} != {%r}" % (f, f))
239 self.assertTrue({f : None} == {f: None}, "{%r : None} != "
Mark Dickinson4a1f5932008-11-12 23:23:36 +0000240 "{%r : None}" % (f, f))
241
242 # identical containers
243 l, t, s, d = [f], (f,), {f}, {f: None}
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000244 self.assertTrue(l == l, "[%r] not equal to itself" % f)
245 self.assertTrue(t == t, "(%r,) not equal to itself" % f)
246 self.assertTrue(s == s, "{%r} not equal to itself" % f)
247 self.assertTrue(d == d, "{%r : None} not equal to itself" % f)
Mark Dickinson4a1f5932008-11-12 23:23:36 +0000248
Mark Dickinson9ab44b52009-12-30 16:22:49 +0000249 def assertEqualAndEqualSign(self, a, b):
250 # fail unless a == b and a and b have the same sign bit;
251 # the only difference from assertEqual is that this test
Ezio Melotti13925002011-03-16 11:05:33 +0200252 # distinguishes -0.0 and 0.0.
Mark Dickinson9ab44b52009-12-30 16:22:49 +0000253 self.assertEqual((a, copysign(1.0, a)), (b, copysign(1.0, b)))
254
Eric Smith3ab08ca2010-12-04 15:17:38 +0000255 @support.requires_IEEE_754
Mark Dickinsond2a9b202010-12-04 12:25:30 +0000256 def test_float_mod(self):
257 # Check behaviour of % operator for IEEE 754 special cases.
258 # In particular, check signs of zeros.
259 mod = operator.mod
260
261 self.assertEqualAndEqualSign(mod(-1.0, 1.0), 0.0)
262 self.assertEqualAndEqualSign(mod(-1e-100, 1.0), 1.0)
263 self.assertEqualAndEqualSign(mod(-0.0, 1.0), 0.0)
264 self.assertEqualAndEqualSign(mod(0.0, 1.0), 0.0)
265 self.assertEqualAndEqualSign(mod(1e-100, 1.0), 1e-100)
266 self.assertEqualAndEqualSign(mod(1.0, 1.0), 0.0)
267
268 self.assertEqualAndEqualSign(mod(-1.0, -1.0), -0.0)
269 self.assertEqualAndEqualSign(mod(-1e-100, -1.0), -1e-100)
270 self.assertEqualAndEqualSign(mod(-0.0, -1.0), -0.0)
271 self.assertEqualAndEqualSign(mod(0.0, -1.0), -0.0)
272 self.assertEqualAndEqualSign(mod(1e-100, -1.0), -1.0)
273 self.assertEqualAndEqualSign(mod(1.0, -1.0), -0.0)
274
Eric Smith3ab08ca2010-12-04 15:17:38 +0000275 @support.requires_IEEE_754
Mark Dickinson9ab44b52009-12-30 16:22:49 +0000276 def test_float_pow(self):
277 # test builtin pow and ** operator for IEEE 754 special cases.
278 # Special cases taken from section F.9.4.4 of the C99 specification
279
280 for pow_op in pow, operator.pow:
281 # x**NAN is NAN for any x except 1
282 self.assertTrue(isnan(pow_op(-INF, NAN)))
283 self.assertTrue(isnan(pow_op(-2.0, NAN)))
284 self.assertTrue(isnan(pow_op(-1.0, NAN)))
285 self.assertTrue(isnan(pow_op(-0.5, NAN)))
286 self.assertTrue(isnan(pow_op(-0.0, NAN)))
287 self.assertTrue(isnan(pow_op(0.0, NAN)))
288 self.assertTrue(isnan(pow_op(0.5, NAN)))
289 self.assertTrue(isnan(pow_op(2.0, NAN)))
290 self.assertTrue(isnan(pow_op(INF, NAN)))
291 self.assertTrue(isnan(pow_op(NAN, NAN)))
292
293 # NAN**y is NAN for any y except +-0
294 self.assertTrue(isnan(pow_op(NAN, -INF)))
295 self.assertTrue(isnan(pow_op(NAN, -2.0)))
296 self.assertTrue(isnan(pow_op(NAN, -1.0)))
297 self.assertTrue(isnan(pow_op(NAN, -0.5)))
298 self.assertTrue(isnan(pow_op(NAN, 0.5)))
299 self.assertTrue(isnan(pow_op(NAN, 1.0)))
300 self.assertTrue(isnan(pow_op(NAN, 2.0)))
301 self.assertTrue(isnan(pow_op(NAN, INF)))
302
303 # (+-0)**y raises ZeroDivisionError for y a negative odd integer
304 self.assertRaises(ZeroDivisionError, pow_op, -0.0, -1.0)
305 self.assertRaises(ZeroDivisionError, pow_op, 0.0, -1.0)
306
307 # (+-0)**y raises ZeroDivisionError for y finite and negative
308 # but not an odd integer
309 self.assertRaises(ZeroDivisionError, pow_op, -0.0, -2.0)
310 self.assertRaises(ZeroDivisionError, pow_op, -0.0, -0.5)
311 self.assertRaises(ZeroDivisionError, pow_op, 0.0, -2.0)
312 self.assertRaises(ZeroDivisionError, pow_op, 0.0, -0.5)
313
314 # (+-0)**y is +-0 for y a positive odd integer
315 self.assertEqualAndEqualSign(pow_op(-0.0, 1.0), -0.0)
316 self.assertEqualAndEqualSign(pow_op(0.0, 1.0), 0.0)
317
318 # (+-0)**y is 0 for y finite and positive but not an odd integer
319 self.assertEqualAndEqualSign(pow_op(-0.0, 0.5), 0.0)
320 self.assertEqualAndEqualSign(pow_op(-0.0, 2.0), 0.0)
321 self.assertEqualAndEqualSign(pow_op(0.0, 0.5), 0.0)
322 self.assertEqualAndEqualSign(pow_op(0.0, 2.0), 0.0)
323
324 # (-1)**+-inf is 1
325 self.assertEqualAndEqualSign(pow_op(-1.0, -INF), 1.0)
326 self.assertEqualAndEqualSign(pow_op(-1.0, INF), 1.0)
327
328 # 1**y is 1 for any y, even if y is an infinity or nan
329 self.assertEqualAndEqualSign(pow_op(1.0, -INF), 1.0)
330 self.assertEqualAndEqualSign(pow_op(1.0, -2.0), 1.0)
331 self.assertEqualAndEqualSign(pow_op(1.0, -1.0), 1.0)
332 self.assertEqualAndEqualSign(pow_op(1.0, -0.5), 1.0)
333 self.assertEqualAndEqualSign(pow_op(1.0, -0.0), 1.0)
334 self.assertEqualAndEqualSign(pow_op(1.0, 0.0), 1.0)
335 self.assertEqualAndEqualSign(pow_op(1.0, 0.5), 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(1.0, INF), 1.0)
339 self.assertEqualAndEqualSign(pow_op(1.0, NAN), 1.0)
340
341 # x**+-0 is 1 for any x, even if x is a zero, infinity, or nan
342 self.assertEqualAndEqualSign(pow_op(-INF, 0.0), 1.0)
343 self.assertEqualAndEqualSign(pow_op(-2.0, 0.0), 1.0)
344 self.assertEqualAndEqualSign(pow_op(-1.0, 0.0), 1.0)
345 self.assertEqualAndEqualSign(pow_op(-0.5, 0.0), 1.0)
346 self.assertEqualAndEqualSign(pow_op(-0.0, 0.0), 1.0)
347 self.assertEqualAndEqualSign(pow_op(0.0, 0.0), 1.0)
348 self.assertEqualAndEqualSign(pow_op(0.5, 0.0), 1.0)
349 self.assertEqualAndEqualSign(pow_op(1.0, 0.0), 1.0)
350 self.assertEqualAndEqualSign(pow_op(2.0, 0.0), 1.0)
351 self.assertEqualAndEqualSign(pow_op(INF, 0.0), 1.0)
352 self.assertEqualAndEqualSign(pow_op(NAN, 0.0), 1.0)
353 self.assertEqualAndEqualSign(pow_op(-INF, -0.0), 1.0)
354 self.assertEqualAndEqualSign(pow_op(-2.0, -0.0), 1.0)
355 self.assertEqualAndEqualSign(pow_op(-1.0, -0.0), 1.0)
356 self.assertEqualAndEqualSign(pow_op(-0.5, -0.0), 1.0)
357 self.assertEqualAndEqualSign(pow_op(-0.0, -0.0), 1.0)
358 self.assertEqualAndEqualSign(pow_op(0.0, -0.0), 1.0)
359 self.assertEqualAndEqualSign(pow_op(0.5, -0.0), 1.0)
360 self.assertEqualAndEqualSign(pow_op(1.0, -0.0), 1.0)
361 self.assertEqualAndEqualSign(pow_op(2.0, -0.0), 1.0)
362 self.assertEqualAndEqualSign(pow_op(INF, -0.0), 1.0)
363 self.assertEqualAndEqualSign(pow_op(NAN, -0.0), 1.0)
364
365 # x**y defers to complex pow for finite negative x and
366 # non-integral y.
367 self.assertEqual(type(pow_op(-2.0, -0.5)), complex)
368 self.assertEqual(type(pow_op(-2.0, 0.5)), complex)
369 self.assertEqual(type(pow_op(-1.0, -0.5)), complex)
370 self.assertEqual(type(pow_op(-1.0, 0.5)), complex)
371 self.assertEqual(type(pow_op(-0.5, -0.5)), complex)
372 self.assertEqual(type(pow_op(-0.5, 0.5)), complex)
373
374 # x**-INF is INF for abs(x) < 1
375 self.assertEqualAndEqualSign(pow_op(-0.5, -INF), INF)
376 self.assertEqualAndEqualSign(pow_op(-0.0, -INF), INF)
377 self.assertEqualAndEqualSign(pow_op(0.0, -INF), INF)
378 self.assertEqualAndEqualSign(pow_op(0.5, -INF), INF)
379
380 # x**-INF is 0 for abs(x) > 1
381 self.assertEqualAndEqualSign(pow_op(-INF, -INF), 0.0)
382 self.assertEqualAndEqualSign(pow_op(-2.0, -INF), 0.0)
383 self.assertEqualAndEqualSign(pow_op(2.0, -INF), 0.0)
384 self.assertEqualAndEqualSign(pow_op(INF, -INF), 0.0)
385
386 # x**INF is 0 for abs(x) < 1
387 self.assertEqualAndEqualSign(pow_op(-0.5, INF), 0.0)
388 self.assertEqualAndEqualSign(pow_op(-0.0, INF), 0.0)
389 self.assertEqualAndEqualSign(pow_op(0.0, INF), 0.0)
390 self.assertEqualAndEqualSign(pow_op(0.5, INF), 0.0)
391
392 # x**INF is INF for abs(x) > 1
393 self.assertEqualAndEqualSign(pow_op(-INF, INF), INF)
394 self.assertEqualAndEqualSign(pow_op(-2.0, INF), INF)
395 self.assertEqualAndEqualSign(pow_op(2.0, INF), INF)
396 self.assertEqualAndEqualSign(pow_op(INF, INF), INF)
397
398 # (-INF)**y is -0.0 for y a negative odd integer
399 self.assertEqualAndEqualSign(pow_op(-INF, -1.0), -0.0)
400
401 # (-INF)**y is 0.0 for y negative but not an odd integer
402 self.assertEqualAndEqualSign(pow_op(-INF, -0.5), 0.0)
403 self.assertEqualAndEqualSign(pow_op(-INF, -2.0), 0.0)
404
405 # (-INF)**y is -INF for y a positive odd integer
406 self.assertEqualAndEqualSign(pow_op(-INF, 1.0), -INF)
407
408 # (-INF)**y is INF for y positive but not an odd integer
409 self.assertEqualAndEqualSign(pow_op(-INF, 0.5), INF)
410 self.assertEqualAndEqualSign(pow_op(-INF, 2.0), INF)
411
412 # INF**y is INF for y positive
413 self.assertEqualAndEqualSign(pow_op(INF, 0.5), INF)
414 self.assertEqualAndEqualSign(pow_op(INF, 1.0), INF)
415 self.assertEqualAndEqualSign(pow_op(INF, 2.0), INF)
416
417 # INF**y is 0.0 for y negative
418 self.assertEqualAndEqualSign(pow_op(INF, -2.0), 0.0)
419 self.assertEqualAndEqualSign(pow_op(INF, -1.0), 0.0)
420 self.assertEqualAndEqualSign(pow_op(INF, -0.5), 0.0)
421
422 # basic checks not covered by the special cases above
423 self.assertEqualAndEqualSign(pow_op(-2.0, -2.0), 0.25)
424 self.assertEqualAndEqualSign(pow_op(-2.0, -1.0), -0.5)
425 self.assertEqualAndEqualSign(pow_op(-2.0, -0.0), 1.0)
426 self.assertEqualAndEqualSign(pow_op(-2.0, 0.0), 1.0)
427 self.assertEqualAndEqualSign(pow_op(-2.0, 1.0), -2.0)
428 self.assertEqualAndEqualSign(pow_op(-2.0, 2.0), 4.0)
429 self.assertEqualAndEqualSign(pow_op(-1.0, -2.0), 1.0)
430 self.assertEqualAndEqualSign(pow_op(-1.0, -1.0), -1.0)
431 self.assertEqualAndEqualSign(pow_op(-1.0, -0.0), 1.0)
432 self.assertEqualAndEqualSign(pow_op(-1.0, 0.0), 1.0)
433 self.assertEqualAndEqualSign(pow_op(-1.0, 1.0), -1.0)
434 self.assertEqualAndEqualSign(pow_op(-1.0, 2.0), 1.0)
435 self.assertEqualAndEqualSign(pow_op(2.0, -2.0), 0.25)
436 self.assertEqualAndEqualSign(pow_op(2.0, -1.0), 0.5)
437 self.assertEqualAndEqualSign(pow_op(2.0, -0.0), 1.0)
438 self.assertEqualAndEqualSign(pow_op(2.0, 0.0), 1.0)
439 self.assertEqualAndEqualSign(pow_op(2.0, 1.0), 2.0)
440 self.assertEqualAndEqualSign(pow_op(2.0, 2.0), 4.0)
441
442 # 1 ** large and -1 ** large; some libms apparently
443 # have problems with these
444 self.assertEqualAndEqualSign(pow_op(1.0, -1e100), 1.0)
445 self.assertEqualAndEqualSign(pow_op(1.0, 1e100), 1.0)
446 self.assertEqualAndEqualSign(pow_op(-1.0, -1e100), 1.0)
447 self.assertEqualAndEqualSign(pow_op(-1.0, 1e100), 1.0)
448
449 # check sign for results that underflow to 0
450 self.assertEqualAndEqualSign(pow_op(-2.0, -2000.0), 0.0)
451 self.assertEqual(type(pow_op(-2.0, -2000.5)), complex)
452 self.assertEqualAndEqualSign(pow_op(-2.0, -2001.0), -0.0)
453 self.assertEqualAndEqualSign(pow_op(2.0, -2000.0), 0.0)
454 self.assertEqualAndEqualSign(pow_op(2.0, -2000.5), 0.0)
455 self.assertEqualAndEqualSign(pow_op(2.0, -2001.0), 0.0)
456 self.assertEqualAndEqualSign(pow_op(-0.5, 2000.0), 0.0)
457 self.assertEqual(type(pow_op(-0.5, 2000.5)), complex)
458 self.assertEqualAndEqualSign(pow_op(-0.5, 2001.0), -0.0)
459 self.assertEqualAndEqualSign(pow_op(0.5, 2000.0), 0.0)
460 self.assertEqualAndEqualSign(pow_op(0.5, 2000.5), 0.0)
461 self.assertEqualAndEqualSign(pow_op(0.5, 2001.0), 0.0)
462
463 # check we don't raise an exception for subnormal results,
464 # and validate signs. Tests currently disabled, since
465 # they fail on systems where a subnormal result from pow
466 # is flushed to zero (e.g. Debian/ia64.)
467 #self.assertTrue(0.0 < pow_op(0.5, 1048) < 1e-315)
468 #self.assertTrue(0.0 < pow_op(-0.5, 1048) < 1e-315)
469 #self.assertTrue(0.0 < pow_op(0.5, 1047) < 1e-315)
470 #self.assertTrue(0.0 > pow_op(-0.5, 1047) > -1e-315)
471 #self.assertTrue(0.0 < pow_op(2.0, -1048) < 1e-315)
472 #self.assertTrue(0.0 < pow_op(-2.0, -1048) < 1e-315)
473 #self.assertTrue(0.0 < pow_op(2.0, -1047) < 1e-315)
474 #self.assertTrue(0.0 > pow_op(-2.0, -1047) > -1e-315)
Mark Dickinson4a1f5932008-11-12 23:23:36 +0000475
476
Benjamin Petersone401c682010-07-02 23:25:44 +0000477@requires_setformat
Michael W. Hudsonba283e22005-05-27 15:23:20 +0000478class FormatFunctionsTestCase(unittest.TestCase):
479
480 def setUp(self):
481 self.save_formats = {'double':float.__getformat__('double'),
482 'float':float.__getformat__('float')}
483
484 def tearDown(self):
485 float.__setformat__('double', self.save_formats['double'])
486 float.__setformat__('float', self.save_formats['float'])
487
488 def test_getformat(self):
Ezio Melottib58e0bd2010-01-23 15:40:09 +0000489 self.assertIn(float.__getformat__('double'),
490 ['unknown', 'IEEE, big-endian', 'IEEE, little-endian'])
491 self.assertIn(float.__getformat__('float'),
492 ['unknown', 'IEEE, big-endian', 'IEEE, little-endian'])
Michael W. Hudsonba283e22005-05-27 15:23:20 +0000493 self.assertRaises(ValueError, float.__getformat__, 'chicken')
494 self.assertRaises(TypeError, float.__getformat__, 1)
495
496 def test_setformat(self):
497 for t in 'double', 'float':
498 float.__setformat__(t, 'unknown')
499 if self.save_formats[t] == 'IEEE, big-endian':
500 self.assertRaises(ValueError, float.__setformat__,
501 t, 'IEEE, little-endian')
502 elif self.save_formats[t] == 'IEEE, little-endian':
503 self.assertRaises(ValueError, float.__setformat__,
504 t, 'IEEE, big-endian')
505 else:
506 self.assertRaises(ValueError, float.__setformat__,
507 t, 'IEEE, big-endian')
508 self.assertRaises(ValueError, float.__setformat__,
509 t, 'IEEE, little-endian')
510 self.assertRaises(ValueError, float.__setformat__,
511 t, 'chicken')
512 self.assertRaises(ValueError, float.__setformat__,
513 'chicken', 'unknown')
514
Guido van Rossum2be161d2007-05-15 20:43:51 +0000515BE_DOUBLE_INF = b'\x7f\xf0\x00\x00\x00\x00\x00\x00'
Guido van Rossum254348e2007-11-21 19:29:53 +0000516LE_DOUBLE_INF = bytes(reversed(BE_DOUBLE_INF))
Guido van Rossum2be161d2007-05-15 20:43:51 +0000517BE_DOUBLE_NAN = b'\x7f\xf8\x00\x00\x00\x00\x00\x00'
Guido van Rossum254348e2007-11-21 19:29:53 +0000518LE_DOUBLE_NAN = bytes(reversed(BE_DOUBLE_NAN))
Michael W. Hudsonba283e22005-05-27 15:23:20 +0000519
Guido van Rossum2be161d2007-05-15 20:43:51 +0000520BE_FLOAT_INF = b'\x7f\x80\x00\x00'
Guido van Rossum254348e2007-11-21 19:29:53 +0000521LE_FLOAT_INF = bytes(reversed(BE_FLOAT_INF))
Guido van Rossum2be161d2007-05-15 20:43:51 +0000522BE_FLOAT_NAN = b'\x7f\xc0\x00\x00'
Guido van Rossum254348e2007-11-21 19:29:53 +0000523LE_FLOAT_NAN = bytes(reversed(BE_FLOAT_NAN))
Michael W. Hudsonba283e22005-05-27 15:23:20 +0000524
525# on non-IEEE platforms, attempting to unpack a bit pattern
526# representing an infinity or a NaN should raise an exception.
527
Benjamin Petersone401c682010-07-02 23:25:44 +0000528@requires_setformat
Michael W. Hudsonba283e22005-05-27 15:23:20 +0000529class UnknownFormatTestCase(unittest.TestCase):
530 def setUp(self):
531 self.save_formats = {'double':float.__getformat__('double'),
532 'float':float.__getformat__('float')}
533 float.__setformat__('double', 'unknown')
534 float.__setformat__('float', 'unknown')
Tim Peters5d36a552005-06-03 22:40:27 +0000535
Michael W. Hudsonba283e22005-05-27 15:23:20 +0000536 def tearDown(self):
537 float.__setformat__('double', self.save_formats['double'])
538 float.__setformat__('float', self.save_formats['float'])
539
540 def test_double_specials_dont_unpack(self):
541 for fmt, data in [('>d', BE_DOUBLE_INF),
542 ('>d', BE_DOUBLE_NAN),
543 ('<d', LE_DOUBLE_INF),
544 ('<d', LE_DOUBLE_NAN)]:
545 self.assertRaises(ValueError, struct.unpack, fmt, data)
546
547 def test_float_specials_dont_unpack(self):
548 for fmt, data in [('>f', BE_FLOAT_INF),
549 ('>f', BE_FLOAT_NAN),
550 ('<f', LE_FLOAT_INF),
551 ('<f', LE_FLOAT_NAN)]:
552 self.assertRaises(ValueError, struct.unpack, fmt, data)
553
554
555# on an IEEE platform, all we guarantee is that bit patterns
556# representing infinities or NaNs do not raise an exception; all else
557# is accident (today).
Guido van Rossum04110fb2007-08-24 16:32:05 +0000558# let's also try to guarantee that -0.0 and 0.0 don't get confused.
Michael W. Hudsonba283e22005-05-27 15:23:20 +0000559
560class IEEEFormatTestCase(unittest.TestCase):
Michael W. Hudsonba283e22005-05-27 15:23:20 +0000561
Eric Smith3ab08ca2010-12-04 15:17:38 +0000562 @support.requires_IEEE_754
Benjamin Petersone401c682010-07-02 23:25:44 +0000563 def test_double_specials_do_unpack(self):
564 for fmt, data in [('>d', BE_DOUBLE_INF),
565 ('>d', BE_DOUBLE_NAN),
566 ('<d', LE_DOUBLE_INF),
567 ('<d', LE_DOUBLE_NAN)]:
568 struct.unpack(fmt, data)
Michael W. Hudsonba283e22005-05-27 15:23:20 +0000569
Eric Smith3ab08ca2010-12-04 15:17:38 +0000570 @support.requires_IEEE_754
Benjamin Petersone401c682010-07-02 23:25:44 +0000571 def test_float_specials_do_unpack(self):
572 for fmt, data in [('>f', BE_FLOAT_INF),
573 ('>f', BE_FLOAT_NAN),
574 ('<f', LE_FLOAT_INF),
575 ('<f', LE_FLOAT_NAN)]:
576 struct.unpack(fmt, data)
Guido van Rossum04110fb2007-08-24 16:32:05 +0000577
Eric Smith8c663262007-08-25 02:26:07 +0000578class FormatTestCase(unittest.TestCase):
Benjamin Petersone401c682010-07-02 23:25:44 +0000579
Eric Smith11fe3e02007-08-31 01:33:06 +0000580 def test_format(self):
Eric Smith8c663262007-08-25 02:26:07 +0000581 # these should be rewritten to use both format(x, spec) and
582 # x.__format__(spec)
583
584 self.assertEqual(format(0.0, 'f'), '0.000000')
585
586 # the default is 'g', except for empty format spec
587 self.assertEqual(format(0.0, ''), '0.0')
588 self.assertEqual(format(0.01, ''), '0.01')
589 self.assertEqual(format(0.01, 'g'), '0.01')
590
Eric Smith63376222009-05-05 14:04:18 +0000591 # empty presentation type should format in the same way as str
592 # (issue 5920)
593 x = 100/7.
594 self.assertEqual(format(x, ''), str(x))
595 self.assertEqual(format(x, '-'), str(x))
596 self.assertEqual(format(x, '>'), str(x))
597 self.assertEqual(format(x, '2'), str(x))
Eric Smith8c663262007-08-25 02:26:07 +0000598
599 self.assertEqual(format(1.0, 'f'), '1.000000')
Eric Smith8c663262007-08-25 02:26:07 +0000600
601 self.assertEqual(format(-1.0, 'f'), '-1.000000')
Eric Smith8c663262007-08-25 02:26:07 +0000602
603 self.assertEqual(format( 1.0, ' f'), ' 1.000000')
604 self.assertEqual(format(-1.0, ' f'), '-1.000000')
605 self.assertEqual(format( 1.0, '+f'), '+1.000000')
606 self.assertEqual(format(-1.0, '+f'), '-1.000000')
607
608 # % formatting
609 self.assertEqual(format(-1.0, '%'), '-100.000000%')
610
611 # conversion to string should fail
612 self.assertRaises(ValueError, format, 3.0, "s")
613
Eric Smith7b69c6c2008-01-27 21:07:59 +0000614 # other format specifiers shouldn't work on floats,
615 # in particular int specifiers
616 for format_spec in ([chr(x) for x in range(ord('a'), ord('z')+1)] +
617 [chr(x) for x in range(ord('A'), ord('Z')+1)]):
618 if not format_spec in 'eEfFgGn%':
619 self.assertRaises(ValueError, format, 0.0, format_spec)
620 self.assertRaises(ValueError, format, 1.0, format_spec)
621 self.assertRaises(ValueError, format, -1.0, format_spec)
622 self.assertRaises(ValueError, format, 1e100, format_spec)
623 self.assertRaises(ValueError, format, -1e100, format_spec)
624 self.assertRaises(ValueError, format, 1e-100, format_spec)
625 self.assertRaises(ValueError, format, -1e-100, format_spec)
Michael W. Hudsonba283e22005-05-27 15:23:20 +0000626
Eric Smith741191f2009-05-06 13:08:15 +0000627 # issue 3382
628 self.assertEqual(format(NAN, 'f'), 'nan')
629 self.assertEqual(format(NAN, 'F'), 'NAN')
630 self.assertEqual(format(INF, 'f'), 'inf')
631 self.assertEqual(format(INF, 'F'), 'INF')
632
Eric Smith3ab08ca2010-12-04 15:17:38 +0000633 @support.requires_IEEE_754
Eric Smith0923d1d2009-04-16 20:16:10 +0000634 def test_format_testfile(self):
Brian Curtin076623b2010-10-31 00:03:45 +0000635 with open(format_testfile) as testfile:
636 for line in testfile:
637 if line.startswith('--'):
638 continue
639 line = line.strip()
640 if not line:
641 continue
Eric Smith0923d1d2009-04-16 20:16:10 +0000642
Brian Curtin076623b2010-10-31 00:03:45 +0000643 lhs, rhs = map(str.strip, line.split('->'))
644 fmt, arg = lhs.split()
645 self.assertEqual(fmt % float(arg), rhs)
646 self.assertEqual(fmt % -float(arg), '-' + rhs)
Eric Smith0923d1d2009-04-16 20:16:10 +0000647
Mark Dickinsond3ca5572009-04-29 18:47:07 +0000648 def test_issue5864(self):
Ezio Melottib3aedd42010-11-20 19:04:17 +0000649 self.assertEqual(format(123.456, '.4'), '123.5')
650 self.assertEqual(format(1234.56, '.4'), '1.235e+03')
651 self.assertEqual(format(12345.6, '.4'), '1.235e+04')
Mark Dickinsond3ca5572009-04-29 18:47:07 +0000652
Mark Dickinson7efad9e2009-04-17 20:59:58 +0000653class ReprTestCase(unittest.TestCase):
654 def test_repr(self):
655 floats_file = open(os.path.join(os.path.split(__file__)[0],
656 'floating_points.txt'))
657 for line in floats_file:
658 line = line.strip()
659 if not line or line.startswith('#'):
660 continue
661 v = eval(line)
662 self.assertEqual(v, eval(repr(v)))
663 floats_file.close()
664
Eric Smith0923d1d2009-04-16 20:16:10 +0000665 @unittest.skipUnless(getattr(sys, 'float_repr_style', '') == 'short',
666 "applies only when using short float repr style")
667 def test_short_repr(self):
668 # test short float repr introduced in Python 3.1. One aspect
669 # of this repr is that we get some degree of str -> float ->
670 # str roundtripping. In particular, for any numeric string
671 # containing 15 or fewer significant digits, those exact same
672 # digits (modulo trailing zeros) should appear in the output.
673 # No more repr(0.03) -> "0.029999999999999999"!
674
675 test_strings = [
676 # output always includes *either* a decimal point and at
677 # least one digit after that point, or an exponent.
678 '0.0',
679 '1.0',
680 '0.01',
681 '0.02',
682 '0.03',
683 '0.04',
684 '0.05',
685 '1.23456789',
686 '10.0',
687 '100.0',
688 # values >= 1e16 get an exponent...
689 '1000000000000000.0',
690 '9999999999999990.0',
691 '1e+16',
692 '1e+17',
693 # ... and so do values < 1e-4
694 '0.001',
695 '0.001001',
696 '0.00010000000000001',
697 '0.0001',
698 '9.999999999999e-05',
699 '1e-05',
700 # values designed to provoke failure if the FPU rounding
701 # precision isn't set correctly
702 '8.72293771110361e+25',
703 '7.47005307342313e+26',
704 '2.86438000439698e+28',
705 '8.89142905246179e+28',
706 '3.08578087079232e+35',
707 ]
708
709 for s in test_strings:
710 negs = '-'+s
711 self.assertEqual(s, repr(float(s)))
712 self.assertEqual(negs, repr(float(negs)))
Mark Dickinson388122d2010-08-04 20:56:28 +0000713 # Since Python 3.2, repr and str are identical
714 self.assertEqual(repr(float(s)), str(float(s)))
715 self.assertEqual(repr(float(negs)), str(float(negs)))
Benjamin Petersone401c682010-07-02 23:25:44 +0000716
Eric Smith3ab08ca2010-12-04 15:17:38 +0000717@support.requires_IEEE_754
Mark Dickinsone6a076d2009-04-18 11:48:33 +0000718class RoundTestCase(unittest.TestCase):
Benjamin Petersone401c682010-07-02 23:25:44 +0000719
Mark Dickinsone6a076d2009-04-18 11:48:33 +0000720 def test_inf_nan(self):
721 self.assertRaises(OverflowError, round, INF)
722 self.assertRaises(OverflowError, round, -INF)
723 self.assertRaises(ValueError, round, NAN)
Mark Dickinson4ca33d12009-11-24 10:59:34 +0000724 self.assertRaises(TypeError, round, INF, 0.0)
725 self.assertRaises(TypeError, round, -INF, 1.0)
726 self.assertRaises(TypeError, round, NAN, "ceci n'est pas un integer")
727 self.assertRaises(TypeError, round, -0.0, 1j)
Mark Dickinsone6a076d2009-04-18 11:48:33 +0000728
Mark Dickinsone6a076d2009-04-18 11:48:33 +0000729 def test_large_n(self):
730 for n in [324, 325, 400, 2**31-1, 2**31, 2**32, 2**100]:
731 self.assertEqual(round(123.456, n), 123.456)
732 self.assertEqual(round(-123.456, n), -123.456)
733 self.assertEqual(round(1e300, n), 1e300)
734 self.assertEqual(round(1e-320, n), 1e-320)
735 self.assertEqual(round(1e150, 300), 1e150)
736 self.assertEqual(round(1e300, 307), 1e300)
737 self.assertEqual(round(-3.1415, 308), -3.1415)
738 self.assertEqual(round(1e150, 309), 1e150)
739 self.assertEqual(round(1.4e-315, 315), 1e-315)
740
Mark Dickinsone6a076d2009-04-18 11:48:33 +0000741 def test_small_n(self):
742 for n in [-308, -309, -400, 1-2**31, -2**31, -2**31-1, -2**100]:
743 self.assertEqual(round(123.456, n), 0.0)
744 self.assertEqual(round(-123.456, n), -0.0)
745 self.assertEqual(round(1e300, n), 0.0)
746 self.assertEqual(round(1e-320, n), 0.0)
747
Mark Dickinsone6a076d2009-04-18 11:48:33 +0000748 def test_overflow(self):
749 self.assertRaises(OverflowError, round, 1.6e308, -308)
750 self.assertRaises(OverflowError, round, -1.7e308, -308)
751
752 @unittest.skipUnless(getattr(sys, 'float_repr_style', '') == 'short',
753 "applies only when using short float repr style")
754 def test_previous_round_bugs(self):
755 # particular cases that have occurred in bug reports
756 self.assertEqual(round(562949953421312.5, 1),
757 562949953421312.5)
758 self.assertEqual(round(56294995342131.5, 3),
759 56294995342131.5)
760 # round-half-even
761 self.assertEqual(round(25.0, -1), 20.0)
762 self.assertEqual(round(35.0, -1), 40.0)
763 self.assertEqual(round(45.0, -1), 40.0)
764 self.assertEqual(round(55.0, -1), 60.0)
765 self.assertEqual(round(65.0, -1), 60.0)
766 self.assertEqual(round(75.0, -1), 80.0)
767 self.assertEqual(round(85.0, -1), 80.0)
768 self.assertEqual(round(95.0, -1), 100.0)
769
770 @unittest.skipUnless(getattr(sys, 'float_repr_style', '') == 'short',
771 "applies only when using short float repr style")
772 def test_matches_float_format(self):
773 # round should give the same results as float formatting
774 for i in range(500):
775 x = i/1000.
776 self.assertEqual(float(format(x, '.0f')), round(x, 0))
777 self.assertEqual(float(format(x, '.1f')), round(x, 1))
778 self.assertEqual(float(format(x, '.2f')), round(x, 2))
779 self.assertEqual(float(format(x, '.3f')), round(x, 3))
780
781 for i in range(5, 5000, 10):
782 x = i/1000.
783 self.assertEqual(float(format(x, '.0f')), round(x, 0))
784 self.assertEqual(float(format(x, '.1f')), round(x, 1))
785 self.assertEqual(float(format(x, '.2f')), round(x, 2))
786 self.assertEqual(float(format(x, '.3f')), round(x, 3))
787
788 for i in range(500):
789 x = random.random()
790 self.assertEqual(float(format(x, '.0f')), round(x, 0))
791 self.assertEqual(float(format(x, '.1f')), round(x, 1))
792 self.assertEqual(float(format(x, '.2f')), round(x, 2))
793 self.assertEqual(float(format(x, '.3f')), round(x, 3))
794
Eric Smith8a10ecc2009-12-02 17:58:24 +0000795 def test_format_specials(self):
796 # Test formatting of nans and infs.
797
798 def test(fmt, value, expected):
799 # Test with both % and format().
800 self.assertEqual(fmt % value, expected, fmt)
Eric Smith984bb582010-11-25 16:08:06 +0000801 fmt = fmt[1:] # strip off the %
802 self.assertEqual(format(value, fmt), expected, fmt)
Eric Smith8a10ecc2009-12-02 17:58:24 +0000803
804 for fmt in ['%e', '%f', '%g', '%.0e', '%.6f', '%.20g',
805 '%#e', '%#f', '%#g', '%#.20e', '%#.15f', '%#.3g']:
806 pfmt = '%+' + fmt[1:]
807 sfmt = '% ' + fmt[1:]
808 test(fmt, INF, 'inf')
809 test(fmt, -INF, '-inf')
810 test(fmt, NAN, 'nan')
811 test(fmt, -NAN, 'nan')
812 # When asking for a sign, it's always provided. nans are
813 # always positive.
814 test(pfmt, INF, '+inf')
815 test(pfmt, -INF, '-inf')
816 test(pfmt, NAN, '+nan')
817 test(pfmt, -NAN, '+nan')
818 # When using ' ' for a sign code, only infs can be negative.
819 # Others have a space.
820 test(sfmt, INF, ' inf')
821 test(sfmt, -INF, '-inf')
822 test(sfmt, NAN, ' nan')
823 test(sfmt, -NAN, ' nan')
824
Steve Dowercb39d1f2015-04-15 16:10:59 -0400825 def test_None_ndigits(self):
826 for x in round(1.23), round(1.23, None), round(1.23, ndigits=None):
827 self.assertEqual(x, 1)
828 self.assertIsInstance(x, int)
829 for x in round(1.78), round(1.78, None), round(1.78, ndigits=None):
830 self.assertEqual(x, 2)
831 self.assertIsInstance(x, int)
832
Mark Dickinsone6a076d2009-04-18 11:48:33 +0000833
Christian Heimes99170a52007-12-19 02:07:34 +0000834# Beginning with Python 2.6 float has cross platform compatible
Georg Brandl2ee470f2008-07-16 12:55:28 +0000835# ways to create and represent inf and nan
Christian Heimes99170a52007-12-19 02:07:34 +0000836class InfNanTest(unittest.TestCase):
837 def test_inf_from_str(self):
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000838 self.assertTrue(isinf(float("inf")))
839 self.assertTrue(isinf(float("+inf")))
840 self.assertTrue(isinf(float("-inf")))
841 self.assertTrue(isinf(float("infinity")))
842 self.assertTrue(isinf(float("+infinity")))
843 self.assertTrue(isinf(float("-infinity")))
Christian Heimes99170a52007-12-19 02:07:34 +0000844
845 self.assertEqual(repr(float("inf")), "inf")
846 self.assertEqual(repr(float("+inf")), "inf")
847 self.assertEqual(repr(float("-inf")), "-inf")
Georg Brandl2ee470f2008-07-16 12:55:28 +0000848 self.assertEqual(repr(float("infinity")), "inf")
849 self.assertEqual(repr(float("+infinity")), "inf")
850 self.assertEqual(repr(float("-infinity")), "-inf")
Christian Heimes99170a52007-12-19 02:07:34 +0000851
852 self.assertEqual(repr(float("INF")), "inf")
853 self.assertEqual(repr(float("+Inf")), "inf")
854 self.assertEqual(repr(float("-iNF")), "-inf")
Georg Brandl2ee470f2008-07-16 12:55:28 +0000855 self.assertEqual(repr(float("Infinity")), "inf")
856 self.assertEqual(repr(float("+iNfInItY")), "inf")
857 self.assertEqual(repr(float("-INFINITY")), "-inf")
Christian Heimes99170a52007-12-19 02:07:34 +0000858
859 self.assertEqual(str(float("inf")), "inf")
860 self.assertEqual(str(float("+inf")), "inf")
861 self.assertEqual(str(float("-inf")), "-inf")
Georg Brandl2ee470f2008-07-16 12:55:28 +0000862 self.assertEqual(str(float("infinity")), "inf")
863 self.assertEqual(str(float("+infinity")), "inf")
864 self.assertEqual(str(float("-infinity")), "-inf")
Christian Heimes99170a52007-12-19 02:07:34 +0000865
866 self.assertRaises(ValueError, float, "info")
867 self.assertRaises(ValueError, float, "+info")
868 self.assertRaises(ValueError, float, "-info")
869 self.assertRaises(ValueError, float, "in")
870 self.assertRaises(ValueError, float, "+in")
871 self.assertRaises(ValueError, float, "-in")
Georg Brandl2ee470f2008-07-16 12:55:28 +0000872 self.assertRaises(ValueError, float, "infinit")
873 self.assertRaises(ValueError, float, "+Infin")
874 self.assertRaises(ValueError, float, "-INFI")
875 self.assertRaises(ValueError, float, "infinitys")
Christian Heimes99170a52007-12-19 02:07:34 +0000876
Mark Dickinsonbd16edd2009-05-20 22:05:25 +0000877 self.assertRaises(ValueError, float, "++Inf")
878 self.assertRaises(ValueError, float, "-+inf")
879 self.assertRaises(ValueError, float, "+-infinity")
880 self.assertRaises(ValueError, float, "--Infinity")
881
Christian Heimes99170a52007-12-19 02:07:34 +0000882 def test_inf_as_str(self):
883 self.assertEqual(repr(1e300 * 1e300), "inf")
884 self.assertEqual(repr(-1e300 * 1e300), "-inf")
885
886 self.assertEqual(str(1e300 * 1e300), "inf")
887 self.assertEqual(str(-1e300 * 1e300), "-inf")
888
889 def test_nan_from_str(self):
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000890 self.assertTrue(isnan(float("nan")))
891 self.assertTrue(isnan(float("+nan")))
892 self.assertTrue(isnan(float("-nan")))
Christian Heimes99170a52007-12-19 02:07:34 +0000893
894 self.assertEqual(repr(float("nan")), "nan")
895 self.assertEqual(repr(float("+nan")), "nan")
896 self.assertEqual(repr(float("-nan")), "nan")
897
898 self.assertEqual(repr(float("NAN")), "nan")
899 self.assertEqual(repr(float("+NAn")), "nan")
900 self.assertEqual(repr(float("-NaN")), "nan")
901
902 self.assertEqual(str(float("nan")), "nan")
903 self.assertEqual(str(float("+nan")), "nan")
904 self.assertEqual(str(float("-nan")), "nan")
905
906 self.assertRaises(ValueError, float, "nana")
907 self.assertRaises(ValueError, float, "+nana")
908 self.assertRaises(ValueError, float, "-nana")
909 self.assertRaises(ValueError, float, "na")
910 self.assertRaises(ValueError, float, "+na")
911 self.assertRaises(ValueError, float, "-na")
912
Mark Dickinsonbd16edd2009-05-20 22:05:25 +0000913 self.assertRaises(ValueError, float, "++nan")
914 self.assertRaises(ValueError, float, "-+NAN")
915 self.assertRaises(ValueError, float, "+-NaN")
916 self.assertRaises(ValueError, float, "--nAn")
917
Christian Heimes99170a52007-12-19 02:07:34 +0000918 def test_nan_as_str(self):
919 self.assertEqual(repr(1e300 * 1e300 * 0), "nan")
920 self.assertEqual(repr(-1e300 * 1e300 * 0), "nan")
921
922 self.assertEqual(str(1e300 * 1e300 * 0), "nan")
923 self.assertEqual(str(-1e300 * 1e300 * 0), "nan")
Christian Heimes827b35c2007-12-10 22:19:17 +0000924
Mark Dickinsone383e822012-04-29 15:31:56 +0100925 def test_inf_signs(self):
926 self.assertEqual(copysign(1.0, float('inf')), 1.0)
927 self.assertEqual(copysign(1.0, float('-inf')), -1.0)
928
929 @unittest.skipUnless(getattr(sys, 'float_repr_style', '') == 'short',
930 "applies only when using short float repr style")
931 def test_nan_signs(self):
932 # When using the dtoa.c code, the sign of float('nan') should
933 # be predictable.
934 self.assertEqual(copysign(1.0, float('nan')), 1.0)
935 self.assertEqual(copysign(1.0, float('-nan')), -1.0)
936
937
Mark Dickinson65fe25e2008-07-16 11:30:51 +0000938fromHex = float.fromhex
939toHex = float.hex
940class HexFloatTestCase(unittest.TestCase):
941 MAX = fromHex('0x.fffffffffffff8p+1024') # max normal
942 MIN = fromHex('0x1p-1022') # min normal
943 TINY = fromHex('0x0.0000000000001p-1022') # min subnormal
944 EPS = fromHex('0x0.0000000000001p0') # diff between 1.0 and next float up
945
946 def identical(self, x, y):
947 # check that floats x and y are identical, or that both
948 # are NaNs
949 if isnan(x) or isnan(y):
950 if isnan(x) == isnan(y):
951 return
952 elif x == y and (x != 0.0 or copysign(1.0, x) == copysign(1.0, y)):
953 return
954 self.fail('%r not identical to %r' % (x, y))
955
956 def test_ends(self):
Mark Dickinson38bbc482008-07-16 11:32:23 +0000957 self.identical(self.MIN, ldexp(1.0, -1022))
958 self.identical(self.TINY, ldexp(1.0, -1074))
959 self.identical(self.EPS, ldexp(1.0, -52))
960 self.identical(self.MAX, 2.*(ldexp(1.0, 1023) - ldexp(1.0, 970)))
Mark Dickinson65fe25e2008-07-16 11:30:51 +0000961
962 def test_invalid_inputs(self):
963 invalid_inputs = [
964 'infi', # misspelt infinities and nans
965 '-Infinit',
966 '++inf',
967 '-+Inf',
968 '--nan',
969 '+-NaN',
970 'snan',
971 'NaNs',
972 'nna',
Mark Dickinsond1ec8b22009-05-11 15:45:15 +0000973 'an',
974 'nf',
975 'nfinity',
976 'inity',
977 'iinity',
Mark Dickinson65fe25e2008-07-16 11:30:51 +0000978 '0xnan',
979 '',
980 ' ',
981 'x1.0p0',
982 '0xX1.0p0',
983 '+ 0x1.0p0', # internal whitespace
984 '- 0x1.0p0',
985 '0 x1.0p0',
986 '0x 1.0p0',
987 '0x1 2.0p0',
988 '+0x1 .0p0',
989 '0x1. 0p0',
990 '-0x1.0 1p0',
991 '-0x1.0 p0',
992 '+0x1.0p +0',
993 '0x1.0p -0',
994 '0x1.0p 0',
995 '+0x1.0p+ 0',
996 '-0x1.0p- 0',
997 '++0x1.0p-0', # double signs
998 '--0x1.0p0',
999 '+-0x1.0p+0',
1000 '-+0x1.0p0',
1001 '0x1.0p++0',
1002 '+0x1.0p+-0',
1003 '-0x1.0p-+0',
1004 '0x1.0p--0',
1005 '0x1.0.p0',
1006 '0x.p0', # no hex digits before or after point
1007 '0x1,p0', # wrong decimal point character
1008 '0x1pa',
1009 '0x1p\uff10', # fullwidth Unicode digits
1010 '\uff10x1p0',
1011 '0x\uff11p0',
1012 '0x1.\uff10p0',
1013 '0x1p0 \n 0x2p0',
1014 '0x1p0\0 0x1p0', # embedded null byte is not end of string
1015 ]
1016 for x in invalid_inputs:
Mark Dickinson589b7952008-08-21 20:05:56 +00001017 try:
1018 result = fromHex(x)
1019 except ValueError:
1020 pass
1021 else:
1022 self.fail('Expected float.fromhex(%r) to raise ValueError; '
1023 'got %r instead' % (x, result))
Mark Dickinson65fe25e2008-07-16 11:30:51 +00001024
1025
Mark Dickinsond1ec8b22009-05-11 15:45:15 +00001026 def test_whitespace(self):
1027 value_pairs = [
1028 ('inf', INF),
1029 ('-Infinity', -INF),
1030 ('nan', NAN),
1031 ('1.0', 1.0),
1032 ('-0x.2', -0.125),
1033 ('-0.0', -0.0)
1034 ]
1035 whitespace = [
1036 '',
1037 ' ',
1038 '\t',
1039 '\n',
1040 '\n \t',
1041 '\f',
1042 '\v',
1043 '\r'
1044 ]
1045 for inp, expected in value_pairs:
1046 for lead in whitespace:
1047 for trail in whitespace:
1048 got = fromHex(lead + inp + trail)
1049 self.identical(got, expected)
1050
1051
Mark Dickinson65fe25e2008-07-16 11:30:51 +00001052 def test_from_hex(self):
1053 MIN = self.MIN;
1054 MAX = self.MAX;
1055 TINY = self.TINY;
1056 EPS = self.EPS;
1057
1058 # two spellings of infinity, with optional signs; case-insensitive
1059 self.identical(fromHex('inf'), INF)
1060 self.identical(fromHex('+Inf'), INF)
1061 self.identical(fromHex('-INF'), -INF)
1062 self.identical(fromHex('iNf'), INF)
1063 self.identical(fromHex('Infinity'), INF)
1064 self.identical(fromHex('+INFINITY'), INF)
1065 self.identical(fromHex('-infinity'), -INF)
1066 self.identical(fromHex('-iNFiNitY'), -INF)
1067
1068 # nans with optional sign; case insensitive
1069 self.identical(fromHex('nan'), NAN)
1070 self.identical(fromHex('+NaN'), NAN)
1071 self.identical(fromHex('-NaN'), NAN)
1072 self.identical(fromHex('-nAN'), NAN)
1073
1074 # variations in input format
1075 self.identical(fromHex('1'), 1.0)
1076 self.identical(fromHex('+1'), 1.0)
1077 self.identical(fromHex('1.'), 1.0)
1078 self.identical(fromHex('1.0'), 1.0)
1079 self.identical(fromHex('1.0p0'), 1.0)
1080 self.identical(fromHex('01'), 1.0)
1081 self.identical(fromHex('01.'), 1.0)
1082 self.identical(fromHex('0x1'), 1.0)
1083 self.identical(fromHex('0x1.'), 1.0)
1084 self.identical(fromHex('0x1.0'), 1.0)
1085 self.identical(fromHex('+0x1.0'), 1.0)
1086 self.identical(fromHex('0x1p0'), 1.0)
1087 self.identical(fromHex('0X1p0'), 1.0)
1088 self.identical(fromHex('0X1P0'), 1.0)
1089 self.identical(fromHex('0x1P0'), 1.0)
1090 self.identical(fromHex('0x1.p0'), 1.0)
1091 self.identical(fromHex('0x1.0p0'), 1.0)
1092 self.identical(fromHex('0x.1p4'), 1.0)
1093 self.identical(fromHex('0x.1p04'), 1.0)
1094 self.identical(fromHex('0x.1p004'), 1.0)
1095 self.identical(fromHex('0x1p+0'), 1.0)
1096 self.identical(fromHex('0x1P-0'), 1.0)
1097 self.identical(fromHex('+0x1p0'), 1.0)
1098 self.identical(fromHex('0x01p0'), 1.0)
1099 self.identical(fromHex('0x1p00'), 1.0)
1100 self.identical(fromHex(' 0x1p0 '), 1.0)
1101 self.identical(fromHex('\n 0x1p0'), 1.0)
1102 self.identical(fromHex('0x1p0 \t'), 1.0)
1103 self.identical(fromHex('0xap0'), 10.0)
1104 self.identical(fromHex('0xAp0'), 10.0)
1105 self.identical(fromHex('0xaP0'), 10.0)
1106 self.identical(fromHex('0xAP0'), 10.0)
1107 self.identical(fromHex('0xbep0'), 190.0)
1108 self.identical(fromHex('0xBep0'), 190.0)
1109 self.identical(fromHex('0xbEp0'), 190.0)
1110 self.identical(fromHex('0XBE0P-4'), 190.0)
1111 self.identical(fromHex('0xBEp0'), 190.0)
1112 self.identical(fromHex('0xB.Ep4'), 190.0)
1113 self.identical(fromHex('0x.BEp8'), 190.0)
1114 self.identical(fromHex('0x.0BEp12'), 190.0)
1115
1116 # moving the point around
1117 pi = fromHex('0x1.921fb54442d18p1')
1118 self.identical(fromHex('0x.006487ed5110b46p11'), pi)
1119 self.identical(fromHex('0x.00c90fdaa22168cp10'), pi)
1120 self.identical(fromHex('0x.01921fb54442d18p9'), pi)
1121 self.identical(fromHex('0x.03243f6a8885a3p8'), pi)
1122 self.identical(fromHex('0x.06487ed5110b46p7'), pi)
1123 self.identical(fromHex('0x.0c90fdaa22168cp6'), pi)
1124 self.identical(fromHex('0x.1921fb54442d18p5'), pi)
1125 self.identical(fromHex('0x.3243f6a8885a3p4'), pi)
1126 self.identical(fromHex('0x.6487ed5110b46p3'), pi)
1127 self.identical(fromHex('0x.c90fdaa22168cp2'), pi)
1128 self.identical(fromHex('0x1.921fb54442d18p1'), pi)
1129 self.identical(fromHex('0x3.243f6a8885a3p0'), pi)
1130 self.identical(fromHex('0x6.487ed5110b46p-1'), pi)
1131 self.identical(fromHex('0xc.90fdaa22168cp-2'), pi)
1132 self.identical(fromHex('0x19.21fb54442d18p-3'), pi)
1133 self.identical(fromHex('0x32.43f6a8885a3p-4'), pi)
1134 self.identical(fromHex('0x64.87ed5110b46p-5'), pi)
1135 self.identical(fromHex('0xc9.0fdaa22168cp-6'), pi)
1136 self.identical(fromHex('0x192.1fb54442d18p-7'), pi)
1137 self.identical(fromHex('0x324.3f6a8885a3p-8'), pi)
1138 self.identical(fromHex('0x648.7ed5110b46p-9'), pi)
1139 self.identical(fromHex('0xc90.fdaa22168cp-10'), pi)
1140 self.identical(fromHex('0x1921.fb54442d18p-11'), pi)
1141 # ...
1142 self.identical(fromHex('0x1921fb54442d1.8p-47'), pi)
1143 self.identical(fromHex('0x3243f6a8885a3p-48'), pi)
1144 self.identical(fromHex('0x6487ed5110b46p-49'), pi)
1145 self.identical(fromHex('0xc90fdaa22168cp-50'), pi)
1146 self.identical(fromHex('0x1921fb54442d18p-51'), pi)
1147 self.identical(fromHex('0x3243f6a8885a30p-52'), pi)
1148 self.identical(fromHex('0x6487ed5110b460p-53'), pi)
1149 self.identical(fromHex('0xc90fdaa22168c0p-54'), pi)
1150 self.identical(fromHex('0x1921fb54442d180p-55'), pi)
1151
1152
1153 # results that should overflow...
1154 self.assertRaises(OverflowError, fromHex, '-0x1p1024')
1155 self.assertRaises(OverflowError, fromHex, '0x1p+1025')
1156 self.assertRaises(OverflowError, fromHex, '+0X1p1030')
1157 self.assertRaises(OverflowError, fromHex, '-0x1p+1100')
1158 self.assertRaises(OverflowError, fromHex, '0X1p123456789123456789')
1159 self.assertRaises(OverflowError, fromHex, '+0X.8p+1025')
1160 self.assertRaises(OverflowError, fromHex, '+0x0.8p1025')
1161 self.assertRaises(OverflowError, fromHex, '-0x0.4p1026')
1162 self.assertRaises(OverflowError, fromHex, '0X2p+1023')
1163 self.assertRaises(OverflowError, fromHex, '0x2.p1023')
1164 self.assertRaises(OverflowError, fromHex, '-0x2.0p+1023')
1165 self.assertRaises(OverflowError, fromHex, '+0X4p+1022')
1166 self.assertRaises(OverflowError, fromHex, '0x1.ffffffffffffffp+1023')
1167 self.assertRaises(OverflowError, fromHex, '-0X1.fffffffffffff9p1023')
1168 self.assertRaises(OverflowError, fromHex, '0X1.fffffffffffff8p1023')
1169 self.assertRaises(OverflowError, fromHex, '+0x3.fffffffffffffp1022')
1170 self.assertRaises(OverflowError, fromHex, '0x3fffffffffffffp+970')
1171 self.assertRaises(OverflowError, fromHex, '0x10000000000000000p960')
1172 self.assertRaises(OverflowError, fromHex, '-0Xffffffffffffffffp960')
1173
1174 # ...and those that round to +-max float
1175 self.identical(fromHex('+0x1.fffffffffffffp+1023'), MAX)
1176 self.identical(fromHex('-0X1.fffffffffffff7p1023'), -MAX)
1177 self.identical(fromHex('0X1.fffffffffffff7fffffffffffffp1023'), MAX)
1178
1179 # zeros
1180 self.identical(fromHex('0x0p0'), 0.0)
1181 self.identical(fromHex('0x0p1000'), 0.0)
1182 self.identical(fromHex('-0x0p1023'), -0.0)
1183 self.identical(fromHex('0X0p1024'), 0.0)
1184 self.identical(fromHex('-0x0p1025'), -0.0)
1185 self.identical(fromHex('0X0p2000'), 0.0)
1186 self.identical(fromHex('0x0p123456789123456789'), 0.0)
1187 self.identical(fromHex('-0X0p-0'), -0.0)
1188 self.identical(fromHex('-0X0p-1000'), -0.0)
1189 self.identical(fromHex('0x0p-1023'), 0.0)
1190 self.identical(fromHex('-0X0p-1024'), -0.0)
1191 self.identical(fromHex('-0x0p-1025'), -0.0)
1192 self.identical(fromHex('-0x0p-1072'), -0.0)
1193 self.identical(fromHex('0X0p-1073'), 0.0)
1194 self.identical(fromHex('-0x0p-1074'), -0.0)
1195 self.identical(fromHex('0x0p-1075'), 0.0)
1196 self.identical(fromHex('0X0p-1076'), 0.0)
1197 self.identical(fromHex('-0X0p-2000'), -0.0)
1198 self.identical(fromHex('-0x0p-123456789123456789'), -0.0)
1199
1200 # values that should underflow to 0
1201 self.identical(fromHex('0X1p-1075'), 0.0)
1202 self.identical(fromHex('-0X1p-1075'), -0.0)
1203 self.identical(fromHex('-0x1p-123456789123456789'), -0.0)
1204 self.identical(fromHex('0x1.00000000000000001p-1075'), TINY)
1205 self.identical(fromHex('-0x1.1p-1075'), -TINY)
1206 self.identical(fromHex('0x1.fffffffffffffffffp-1075'), TINY)
1207
1208 # check round-half-even is working correctly near 0 ...
1209 self.identical(fromHex('0x1p-1076'), 0.0)
1210 self.identical(fromHex('0X2p-1076'), 0.0)
1211 self.identical(fromHex('0X3p-1076'), TINY)
1212 self.identical(fromHex('0x4p-1076'), TINY)
1213 self.identical(fromHex('0X5p-1076'), TINY)
1214 self.identical(fromHex('0X6p-1076'), 2*TINY)
1215 self.identical(fromHex('0x7p-1076'), 2*TINY)
1216 self.identical(fromHex('0X8p-1076'), 2*TINY)
1217 self.identical(fromHex('0X9p-1076'), 2*TINY)
1218 self.identical(fromHex('0xap-1076'), 2*TINY)
1219 self.identical(fromHex('0Xbp-1076'), 3*TINY)
1220 self.identical(fromHex('0xcp-1076'), 3*TINY)
1221 self.identical(fromHex('0Xdp-1076'), 3*TINY)
1222 self.identical(fromHex('0Xep-1076'), 4*TINY)
1223 self.identical(fromHex('0xfp-1076'), 4*TINY)
1224 self.identical(fromHex('0x10p-1076'), 4*TINY)
1225 self.identical(fromHex('-0x1p-1076'), -0.0)
1226 self.identical(fromHex('-0X2p-1076'), -0.0)
1227 self.identical(fromHex('-0x3p-1076'), -TINY)
1228 self.identical(fromHex('-0X4p-1076'), -TINY)
1229 self.identical(fromHex('-0x5p-1076'), -TINY)
1230 self.identical(fromHex('-0x6p-1076'), -2*TINY)
1231 self.identical(fromHex('-0X7p-1076'), -2*TINY)
1232 self.identical(fromHex('-0X8p-1076'), -2*TINY)
1233 self.identical(fromHex('-0X9p-1076'), -2*TINY)
1234 self.identical(fromHex('-0Xap-1076'), -2*TINY)
1235 self.identical(fromHex('-0xbp-1076'), -3*TINY)
1236 self.identical(fromHex('-0xcp-1076'), -3*TINY)
1237 self.identical(fromHex('-0Xdp-1076'), -3*TINY)
1238 self.identical(fromHex('-0xep-1076'), -4*TINY)
1239 self.identical(fromHex('-0Xfp-1076'), -4*TINY)
1240 self.identical(fromHex('-0X10p-1076'), -4*TINY)
1241
1242 # ... and near MIN ...
1243 self.identical(fromHex('0x0.ffffffffffffd6p-1022'), MIN-3*TINY)
1244 self.identical(fromHex('0x0.ffffffffffffd8p-1022'), MIN-2*TINY)
1245 self.identical(fromHex('0x0.ffffffffffffdap-1022'), MIN-2*TINY)
1246 self.identical(fromHex('0x0.ffffffffffffdcp-1022'), MIN-2*TINY)
1247 self.identical(fromHex('0x0.ffffffffffffdep-1022'), MIN-2*TINY)
1248 self.identical(fromHex('0x0.ffffffffffffe0p-1022'), MIN-2*TINY)
1249 self.identical(fromHex('0x0.ffffffffffffe2p-1022'), MIN-2*TINY)
1250 self.identical(fromHex('0x0.ffffffffffffe4p-1022'), MIN-2*TINY)
1251 self.identical(fromHex('0x0.ffffffffffffe6p-1022'), MIN-2*TINY)
1252 self.identical(fromHex('0x0.ffffffffffffe8p-1022'), MIN-2*TINY)
1253 self.identical(fromHex('0x0.ffffffffffffeap-1022'), MIN-TINY)
1254 self.identical(fromHex('0x0.ffffffffffffecp-1022'), MIN-TINY)
1255 self.identical(fromHex('0x0.ffffffffffffeep-1022'), MIN-TINY)
1256 self.identical(fromHex('0x0.fffffffffffff0p-1022'), MIN-TINY)
1257 self.identical(fromHex('0x0.fffffffffffff2p-1022'), MIN-TINY)
1258 self.identical(fromHex('0x0.fffffffffffff4p-1022'), MIN-TINY)
1259 self.identical(fromHex('0x0.fffffffffffff6p-1022'), MIN-TINY)
1260 self.identical(fromHex('0x0.fffffffffffff8p-1022'), MIN)
1261 self.identical(fromHex('0x0.fffffffffffffap-1022'), MIN)
1262 self.identical(fromHex('0x0.fffffffffffffcp-1022'), MIN)
1263 self.identical(fromHex('0x0.fffffffffffffep-1022'), MIN)
1264 self.identical(fromHex('0x1.00000000000000p-1022'), MIN)
1265 self.identical(fromHex('0x1.00000000000002p-1022'), MIN)
1266 self.identical(fromHex('0x1.00000000000004p-1022'), MIN)
1267 self.identical(fromHex('0x1.00000000000006p-1022'), MIN)
1268 self.identical(fromHex('0x1.00000000000008p-1022'), MIN)
1269 self.identical(fromHex('0x1.0000000000000ap-1022'), MIN+TINY)
1270 self.identical(fromHex('0x1.0000000000000cp-1022'), MIN+TINY)
1271 self.identical(fromHex('0x1.0000000000000ep-1022'), MIN+TINY)
1272 self.identical(fromHex('0x1.00000000000010p-1022'), MIN+TINY)
1273 self.identical(fromHex('0x1.00000000000012p-1022'), MIN+TINY)
1274 self.identical(fromHex('0x1.00000000000014p-1022'), MIN+TINY)
1275 self.identical(fromHex('0x1.00000000000016p-1022'), MIN+TINY)
1276 self.identical(fromHex('0x1.00000000000018p-1022'), MIN+2*TINY)
1277
1278 # ... and near 1.0.
1279 self.identical(fromHex('0x0.fffffffffffff0p0'), 1.0-EPS)
1280 self.identical(fromHex('0x0.fffffffffffff1p0'), 1.0-EPS)
1281 self.identical(fromHex('0X0.fffffffffffff2p0'), 1.0-EPS)
1282 self.identical(fromHex('0x0.fffffffffffff3p0'), 1.0-EPS)
1283 self.identical(fromHex('0X0.fffffffffffff4p0'), 1.0-EPS)
1284 self.identical(fromHex('0X0.fffffffffffff5p0'), 1.0-EPS/2)
1285 self.identical(fromHex('0X0.fffffffffffff6p0'), 1.0-EPS/2)
1286 self.identical(fromHex('0x0.fffffffffffff7p0'), 1.0-EPS/2)
1287 self.identical(fromHex('0x0.fffffffffffff8p0'), 1.0-EPS/2)
1288 self.identical(fromHex('0X0.fffffffffffff9p0'), 1.0-EPS/2)
1289 self.identical(fromHex('0X0.fffffffffffffap0'), 1.0-EPS/2)
1290 self.identical(fromHex('0x0.fffffffffffffbp0'), 1.0-EPS/2)
1291 self.identical(fromHex('0X0.fffffffffffffcp0'), 1.0)
1292 self.identical(fromHex('0x0.fffffffffffffdp0'), 1.0)
1293 self.identical(fromHex('0X0.fffffffffffffep0'), 1.0)
1294 self.identical(fromHex('0x0.ffffffffffffffp0'), 1.0)
1295 self.identical(fromHex('0X1.00000000000000p0'), 1.0)
1296 self.identical(fromHex('0X1.00000000000001p0'), 1.0)
1297 self.identical(fromHex('0x1.00000000000002p0'), 1.0)
1298 self.identical(fromHex('0X1.00000000000003p0'), 1.0)
1299 self.identical(fromHex('0x1.00000000000004p0'), 1.0)
1300 self.identical(fromHex('0X1.00000000000005p0'), 1.0)
1301 self.identical(fromHex('0X1.00000000000006p0'), 1.0)
1302 self.identical(fromHex('0X1.00000000000007p0'), 1.0)
1303 self.identical(fromHex('0x1.00000000000007ffffffffffffffffffffp0'),
1304 1.0)
1305 self.identical(fromHex('0x1.00000000000008p0'), 1.0)
1306 self.identical(fromHex('0x1.00000000000008000000000000000001p0'),
1307 1+EPS)
1308 self.identical(fromHex('0X1.00000000000009p0'), 1.0+EPS)
1309 self.identical(fromHex('0x1.0000000000000ap0'), 1.0+EPS)
1310 self.identical(fromHex('0x1.0000000000000bp0'), 1.0+EPS)
1311 self.identical(fromHex('0X1.0000000000000cp0'), 1.0+EPS)
1312 self.identical(fromHex('0x1.0000000000000dp0'), 1.0+EPS)
1313 self.identical(fromHex('0x1.0000000000000ep0'), 1.0+EPS)
1314 self.identical(fromHex('0X1.0000000000000fp0'), 1.0+EPS)
1315 self.identical(fromHex('0x1.00000000000010p0'), 1.0+EPS)
1316 self.identical(fromHex('0X1.00000000000011p0'), 1.0+EPS)
1317 self.identical(fromHex('0x1.00000000000012p0'), 1.0+EPS)
1318 self.identical(fromHex('0X1.00000000000013p0'), 1.0+EPS)
1319 self.identical(fromHex('0X1.00000000000014p0'), 1.0+EPS)
1320 self.identical(fromHex('0x1.00000000000015p0'), 1.0+EPS)
1321 self.identical(fromHex('0x1.00000000000016p0'), 1.0+EPS)
1322 self.identical(fromHex('0X1.00000000000017p0'), 1.0+EPS)
1323 self.identical(fromHex('0x1.00000000000017ffffffffffffffffffffp0'),
1324 1.0+EPS)
1325 self.identical(fromHex('0x1.00000000000018p0'), 1.0+2*EPS)
1326 self.identical(fromHex('0X1.00000000000018000000000000000001p0'),
1327 1.0+2*EPS)
1328 self.identical(fromHex('0x1.00000000000019p0'), 1.0+2*EPS)
1329 self.identical(fromHex('0X1.0000000000001ap0'), 1.0+2*EPS)
1330 self.identical(fromHex('0X1.0000000000001bp0'), 1.0+2*EPS)
1331 self.identical(fromHex('0x1.0000000000001cp0'), 1.0+2*EPS)
1332 self.identical(fromHex('0x1.0000000000001dp0'), 1.0+2*EPS)
1333 self.identical(fromHex('0x1.0000000000001ep0'), 1.0+2*EPS)
1334 self.identical(fromHex('0X1.0000000000001fp0'), 1.0+2*EPS)
1335 self.identical(fromHex('0x1.00000000000020p0'), 1.0+2*EPS)
1336
1337 def test_roundtrip(self):
1338 def roundtrip(x):
1339 return fromHex(toHex(x))
1340
1341 for x in [NAN, INF, self.MAX, self.MIN, self.MIN-self.TINY, self.TINY, 0.0]:
1342 self.identical(x, roundtrip(x))
1343 self.identical(-x, roundtrip(-x))
1344
1345 # fromHex(toHex(x)) should exactly recover x, for any non-NaN float x.
1346 import random
1347 for i in range(10000):
1348 e = random.randrange(-1200, 1200)
1349 m = random.random()
1350 s = random.choice([1.0, -1.0])
1351 try:
1352 x = s*ldexp(m, e)
1353 except OverflowError:
1354 pass
1355 else:
1356 self.identical(x, fromHex(toHex(x)))
1357
Serhiy Storchakaea36c942016-05-12 10:37:58 +03001358 def test_subclass(self):
1359 class F(float):
1360 def __new__(cls, value):
1361 return float.__new__(cls, value + 1)
1362
1363 f = F.fromhex((1.5).hex())
1364 self.assertIs(type(f), F)
1365 self.assertEqual(f, 2.5)
1366
1367 class F2(float):
1368 def __init__(self, value):
1369 self.foo = 'bar'
1370
1371 f = F2.fromhex((1.5).hex())
1372 self.assertIs(type(f), F2)
1373 self.assertEqual(f, 1.5)
1374 self.assertEqual(getattr(f, 'foo', 'none'), 'bar')
1375
Christian Heimes53876d92008-04-19 00:31:39 +00001376
Michael W. Hudsonba283e22005-05-27 15:23:20 +00001377if __name__ == '__main__':
Zachary Ware38c707e2015-04-13 15:00:43 -05001378 unittest.main()