this repo has no description
1#!/usr/bin/env python3
2# Copyright (c) Facebook, Inc. and its affiliates. (http://www.facebook.com)
3import unittest
4
5
6class FloatTests(unittest.TestCase):
7 def test_dunder_add_with_non_float_raises_type_error(self):
8 self.assertRaisesRegex(
9 TypeError,
10 "'__add__' .* 'float' object.* a 'int'",
11 float.__add__,
12 2,
13 2.0,
14 )
15
16 def test_dunder_divmod_raises_type_error(self):
17 with self.assertRaises(TypeError):
18 float.__divmod__(1, 1.0)
19
20 def test_dunder_divmod_with_non_number_as_other_returns_not_implemented(self):
21 self.assertIs(float.__divmod__(1.0, "1"), NotImplemented)
22
23 def test_dunder_divmod_with_zero_denominator_raises_zero_division_error(self):
24 with self.assertRaises(ZeroDivisionError):
25 float.__divmod__(1.0, 0.0)
26
27 def test_dunder_divmod_with_negative_zero_denominator_raises_zero_division_error(
28 self,
29 ):
30 with self.assertRaises(ZeroDivisionError):
31 float.__divmod__(1.0, -0.0)
32
33 def test_dunder_divmod_with_zero_numerator(self):
34 floordiv, remainder = float.__divmod__(0.0, 4.0)
35 self.assertEqual(floordiv, 0.0)
36 self.assertEqual(remainder, 0.0)
37
38 def test_dunder_divmod_with_positive_denominator_positive_numerator(self):
39 floordiv, remainder = float.__divmod__(3.25, 1.0)
40 self.assertEqual(floordiv, 3.0)
41 self.assertEqual(remainder, 0.25)
42
43 def test_dunder_divmod_with_negative_denominator_positive_numerator(self):
44 floordiv, remainder = float.__divmod__(-3.25, 1.0)
45 self.assertEqual(floordiv, -4.0)
46 self.assertEqual(remainder, 0.75)
47
48 def test_dunder_divmod_with_negative_denominator_negative_numerator(self):
49 floordiv, remainder = float.__divmod__(-3.25, -1.0)
50 self.assertEqual(floordiv, 3.0)
51 self.assertEqual(remainder, -0.25)
52
53 def test_dunder_divmod_with_positive_denominator_negative_numerator(self):
54 floordiv, remainder = float.__divmod__(3.25, -1.0)
55 self.assertEqual(floordiv, -4.0)
56 self.assertEqual(remainder, -0.75)
57
58 def test_dunder_divmod_with_nan_denominator(self):
59 import math
60
61 floordiv, remainder = float.__divmod__(3.25, float("nan"))
62 self.assertTrue(math.isnan(floordiv))
63 self.assertTrue(math.isnan(remainder))
64
65 def test_dunder_divmod_with_nan_numerator(self):
66 import math
67
68 floordiv, remainder = float.__divmod__(float("nan"), 1.0)
69 self.assertTrue(math.isnan(floordiv))
70 self.assertTrue(math.isnan(remainder))
71
72 def test_dunder_divmod_with_negative_nan_denominator(self):
73 import math
74
75 floordiv, remainder = float.__divmod__(3.25, float("-nan"))
76 self.assertTrue(math.isnan(floordiv))
77 self.assertTrue(math.isnan(remainder))
78
79 def test_dunder_divmod_with_negative_nan_numerator(self):
80 import math
81
82 floordiv, remainder = float.__divmod__(float("-nan"), 1.0)
83 self.assertTrue(math.isnan(floordiv))
84 self.assertTrue(math.isnan(remainder))
85
86 def test_dunder_divmod_with_inf_denominator(self):
87 floordiv, remainder = float.__divmod__(3.25, float("inf"))
88 self.assertEqual(floordiv, 0.0)
89 self.assertEqual(remainder, 3.25)
90
91 def test_dunder_divmod_with_inf_numerator(self):
92 import math
93
94 floordiv, remainder = float.__divmod__(float("inf"), 1.0)
95 self.assertTrue(math.isnan(floordiv))
96 self.assertTrue(math.isnan(remainder))
97
98 def test_dunder_divmod_with_negative_inf_denominator(self):
99 floordiv, remainder = float.__divmod__(3.25, float("-inf"))
100 self.assertEqual(floordiv, -1.0)
101 self.assertEqual(remainder, -float("inf"))
102
103 def test_dunder_divmod_with_negative_inf_numerator(self):
104 import math
105
106 floordiv, remainder = float.__divmod__(float("-inf"), 1.0)
107 self.assertTrue(math.isnan(floordiv))
108 self.assertTrue(math.isnan(remainder))
109
110 def test_dunder_divmod_with_big_numerator(self):
111 floordiv, remainder = float.__divmod__(1e200, 1.0)
112 self.assertEqual(floordiv, 1e200)
113 self.assertEqual(remainder, 0.0)
114
115 def test_dunder_divmod_with_big_denominator(self):
116 floordiv, remainder = float.__divmod__(1.0, 1e200)
117 self.assertEqual(floordiv, 0.0)
118 self.assertEqual(remainder, 1.0)
119
120 def test_dunder_divmod_with_negative_zero_numerator(self):
121 floordiv, remainder = float.__divmod__(-0.0, 4.0)
122 self.assertTrue(str(floordiv) == "-0.0")
123 self.assertEqual(remainder, 0.0)
124
125 def test_dunder_floordiv_raises_type_error(self):
126 with self.assertRaises(TypeError):
127 float.__floordiv__(1, 1.0)
128
129 def test_dunder_floordiv_with_non_number_as_other_returns_not_implemented(self):
130 self.assertIs(float.__floordiv__(1.0, "1"), NotImplemented)
131
132 def test_dunder_floordiv_with_zero_denominator_raises_zero_division_error(self):
133 with self.assertRaises(ZeroDivisionError):
134 float.__floordiv__(1.0, 0.0)
135
136 def test_dunder_floordiv_returns_floor_quotient(self):
137 self.assertEqual(float.__floordiv__(3.25, -1.0), -4.0)
138
139 def test_dunder_getformat_with_float_or_double_returns_format(self):
140 import sys
141
142 self.assertEqual(float.__getformat__("double"), f"IEEE, {sys.byteorder}-endian")
143 self.assertEqual(float.__getformat__("float"), f"IEEE, {sys.byteorder}-endian")
144
145 def test_dunder_getformat_with_non_float_or_double_raises_value_error(self):
146 with self.assertRaises(ValueError):
147 float.__getformat__("unknown")
148
149 def test_dunder_hash_from_non_finites_returns_well_known_values(self):
150 import sys
151
152 self.assertEqual(float.__hash__(float("inf")), sys.hash_info.inf)
153 self.assertEqual(float.__hash__(float("-inf")), -(sys.hash_info.inf))
154 self.assertEqual(float.__hash__(float("nan")), sys.hash_info.nan)
155
156 def test_dunder_hash_returns_int(self):
157 self.assertIsInstance(float.__hash__(0.0), int)
158 self.assertIsInstance(float.__hash__(-1.0), int)
159 self.assertIsInstance(float.__hash__(42.34532), int)
160 self.assertIsInstance(float.__hash__(1.79769e308), int)
161
162 def test_dunder_hash_matches_int_dunder_hash(self):
163 self.assertEqual(float.__hash__(0.0), int.__hash__(0))
164 self.assertEqual(float.__hash__(-0.0), int.__hash__(0))
165 self.assertEqual(float.__hash__(1.0), int.__hash__(1))
166 self.assertEqual(float.__hash__(-1.0), int.__hash__(-1))
167 self.assertEqual(float.__hash__(42.0), int.__hash__(42))
168 self.assertEqual(float.__hash__(-99.0), int.__hash__(-99))
169 self.assertEqual(
170 float.__hash__(9.313203665422767e55), int.__hash__(0x3CC58055CE060C << 132)
171 )
172 self.assertEqual(
173 float.__hash__(-7.26682022207011e41), int.__hash__(-0x85786CAA960EE << 88)
174 )
175
176 def test_dunder_hash_with_negative_exponent_returns_int(self):
177 self.assertEqual(float.__hash__(0.5), 1 << 60)
178
179 import sys
180
181 # the following only works for the given modulus.
182 self.assertEqual(sys.hash_info.modulus, (1 << 61) - 1)
183 self.assertEqual(float.__hash__(6.716542360700249e-22), 0xCAFEBABE00000)
184
185 def test_dunder_hash_with_subnormals_returns_int(self):
186 import sys
187
188 # The following tests assume a specific modulus and need to be adapted
189 # if that changes.
190 self.assertEqual(sys.hash_info.modulus, (1 << 61) - 1)
191 # This is the smallest number that is not a subnormal yet.
192 self.assertEqual(float.__hash__(2.2250738585072014e-308), 1 << 15)
193 # The following are subnormal numbers:
194 self.assertEqual(float.__hash__(1.1125369292536007e-308), 1 << 14)
195 self.assertEqual(float.__hash__(2.225073858507201e-308), 0x1FFFFFFFFF007FFF)
196 self.assertEqual(float.__hash__(5e-324), 1 << 24)
197 # This is the smallest number that is not a subnormal yet.
198 self.assertEqual(float.__hash__(-2.2250738585072014e-308), -1 << 15)
199 # The following are subnormal numbers:
200 self.assertEqual(float.__hash__(-1.1125369292536007e-308), -1 << 14)
201 self.assertEqual(float.__hash__(-2.225073858507201e-308), -0x1FFFFFFFFF007FFF)
202 self.assertEqual(float.__hash__(-5e-324), -1 << 24)
203
204 def test_dunder_hash_matches_bool_dunder_hash(self):
205 self.assertEqual(float.__hash__(float(True)), bool.__hash__(True))
206 self.assertEqual(float.__hash__(float(False)), bool.__hash__(False))
207
208 def test_dunder_hash_with_float_subclass_returns_int(self):
209 class C(float):
210 pass
211
212 self.assertEqual(float.__hash__(C(-77.0)), -77)
213
214 def test_dunder_hash_with_non_float_raises_type_error(self):
215 self.assertRaisesRegex(
216 TypeError,
217 "'__hash__' .* 'float' object.* a 'str'",
218 float.__hash__,
219 "not a float",
220 )
221
222 def test_dunder_int_with_non_float_raise_type_error(self):
223 self.assertRaisesRegex(
224 TypeError,
225 "'__int__' .* 'float' object.* a 'str'",
226 float.__int__,
227 "not a float",
228 )
229
230 def test_dunder_mod_raises_type_error(self):
231 with self.assertRaises(TypeError):
232 float.__mod__(1, 1.0)
233
234 def test_dunder_mod_with_non_number_as_other_returns_not_implemented(self):
235 self.assertIs(float.__mod__(1.0, "1"), NotImplemented)
236
237 def test_dunder_mod_with_zero_denominator_raises_zero_division_error(self):
238 with self.assertRaises(ZeroDivisionError):
239 float.__mod__(1.0, 0.0)
240
241 def test_dunder_mod_returns_remainder(self):
242 self.assertEqual(float.__mod__(3.25, -1.0), -0.75)
243
244 def test_dunder_new_with_non_class_raises_type_error(self):
245 with self.assertRaises(TypeError):
246 float.__new__("not a type")
247
248 def test_dunder_new_with_non_float_subclass_raises_type_error(self):
249 with self.assertRaises(TypeError):
250 float.__new__(int)
251
252 def test_dunder_new_with_default_argument_returns_zero(self):
253 self.assertEqual(float(), 0.0)
254
255 def test_dunder_new_with_float_returns_same_value(self):
256 self.assertEqual(float(1.0), 1.0)
257
258 def test_dunder_new_with_invalid_str_raises_value_error(self):
259 with self.assertRaises(ValueError):
260 float("1880.3a01")
261
262 def test_dunder_new_with_str_returns_float(self):
263 self.assertEqual(float("1.0"), 1.0)
264
265 def test_dunder_new_with_huge_positive_str_returns_inf(self):
266 self.assertEqual(float("1.18973e+4932"), float("inf"))
267
268 def test_dunder_new_with_huge_negative_str_returns_negative_inf(self):
269 self.assertEqual(float("-1.18973e+4932"), float("-inf"))
270
271 def test_dunder_new_with_invalid_bytes_raises_value_error(self):
272 with self.assertRaises(ValueError):
273 float(b"1880.3a01")
274
275 def test_dunder_new_with_bytes_returns_float(self):
276 self.assertEqual(float(b"1.0"), 1.0)
277
278 def test_dunder_new_with_huge_positive_bytes_returns_inf(self):
279 self.assertEqual(float(b"1.18973e+4932"), float("inf"))
280
281 def test_dunder_new_with_huge_negative_bytes_returns_negative_inf(self):
282 self.assertEqual(float(b"-1.18973e+4932"), float("-inf"))
283
284 def test_dunder_new_with_float_subclass_calls_dunder_float(self):
285 class C(float):
286 def __float__(self):
287 return 1.0
288
289 c = C()
290 self.assertEqual(c, 0.0)
291 self.assertEqual(float(c), 1.0)
292
293 def test_dunder_new_calls_type_index(self):
294 class C:
295 def __index__(self):
296 return 42
297
298 c = C()
299 c.__index__ = "not callable"
300 result = float.__new__(float, c)
301 self.assertEqual(result, 42.0)
302
303 def test_dunder_new_calls_float_when_index_and_float_exist(self):
304 class C:
305 def __float__(self):
306 return 41.0
307
308 def __index__(self):
309 return 42
310
311 c = C()
312 c.__index__ = "not callable"
313 result = float.__new__(float, c)
314 self.assertEqual(result, 41.0)
315
316 def test_dunder_new_with_str_subclass_calls_dunder_float(self):
317 class C(str):
318 def __float__(self):
319 return 1.0
320
321 c = C("0.0")
322 self.assertEqual(float(c), 1.0)
323
324 def test_dunder_new_with_int_calls_dunder_float(self):
325 self.assertEqual(float(1), 1.0)
326
327 def test_dunder_new_with_raising_descriptor_propagates_exception(self):
328 class Desc:
329 def __get__(self, obj, type):
330 raise IndexError()
331
332 class C:
333 __float__ = Desc()
334
335 self.assertRaises(IndexError, float, C())
336
337 def test_dunder_new_without_dunder_float_raises_type_error(self):
338 with self.assertRaises(TypeError) as context:
339 float([])
340 self.assertEqual(
341 str(context.exception),
342 "float() argument must be a string or a number, not 'list'",
343 )
344
345 def test_dunder_pow_with_str_returns_float(self):
346 result = float.__pow__(2.0, 4)
347 self.assertIs(type(result), float)
348 self.assertEqual(result, 16.0)
349
350 def test_dunder_pow_with_third_arg_int_raises_type_error(self):
351 with self.assertRaises(TypeError) as context:
352 float.__pow__(2.0, 4.0, 4.0)
353 self.assertIn(
354 "pow() 3rd argument not allowed unless all arguments are integers",
355 str(context.exception),
356 )
357
358 def test_dunder_pow_with_third_arg_none_returns_power_of_first_two_args(self):
359 self.assertEqual(float.__pow__(2.0, 4.0, None), 16.0)
360
361 def test_dunder_rdivmod_raises_type_error(self):
362 with self.assertRaises(TypeError):
363 float.__rdivmod__(1, 1.0)
364
365 def test_dunder_rdivmod_with_non_number_as_other_returns_not_implemented(self):
366 self.assertIs(float.__rdivmod__(1.0, "1"), NotImplemented)
367
368 def test_dunder_rdivmod_with_int_returns_same_result_as_divmod_with_reversed_args(
369 self,
370 ):
371 self.assertEqual(float.__rdivmod__(1.0, 3), float.__divmod__(float(3), 1.0))
372
373 def test_dunder_rdivmod_returns_same_result_as_divmod_with_reversed_args(self):
374 self.assertEqual(float.__rdivmod__(1.0, 3.25), float.__divmod__(3.25, 1.0))
375
376 def test_repr_with_infinity_returns_string(self):
377 self.assertEqual(float.__repr__(float("inf")), "inf")
378 self.assertEqual(float.__repr__(-float("inf")), "-inf")
379
380 def test_repr_with_nan_returns_nan(self):
381 self.assertEqual(float.__repr__(float("nan")), "nan")
382 self.assertEqual(float.__repr__(float("-nan")), "nan")
383
384 def test_repr_returns_string_without_exponent(self):
385 self.assertEqual(float.__repr__(0.0), "0.0")
386 self.assertEqual(float.__repr__(-0.0), "-0.0")
387 self.assertEqual(float.__repr__(1.0), "1.0")
388 self.assertEqual(float.__repr__(-1.0), "-1.0")
389 self.assertEqual(float.__repr__(42.5), "42.5")
390 self.assertEqual(float.__repr__(1.234567891234567), "1.234567891234567")
391 self.assertEqual(float.__repr__(-1.234567891234567), "-1.234567891234567")
392 self.assertEqual(float.__repr__(9.99999999999999e15), "9999999999999990.0")
393 self.assertEqual(float.__repr__(0.0001), "0.0001")
394
395 def test_repr_returns_string_with_exponent(self):
396 self.assertEqual(float.__repr__(1e16), "1e+16")
397 self.assertEqual(float.__repr__(0.00001), "1e-05")
398 self.assertEqual(float.__repr__(1e100), "1e+100")
399 self.assertEqual(float.__repr__(1e-88), "1e-88")
400 self.assertEqual(
401 float.__repr__(1.23456789123456789e123), "1.2345678912345679e+123"
402 )
403 self.assertEqual(
404 float.__repr__(-1.23456789123456789e-123), "-1.2345678912345678e-123"
405 )
406
407 def test_dunder_rfloordiv_raises_type_error(self):
408 with self.assertRaises(TypeError):
409 float.__rfloordiv__(1, 1.0)
410
411 def test_dunder_rfloordiv_with_non_number_as_other_returns_not_implemented(self):
412 self.assertIs(float.__rfloordiv__(1.0, "1"), NotImplemented)
413
414 def test_dunder_rfloordiv_with_int_returns_same_result_as_floordiv(self):
415 self.assertEqual(float.__rfloordiv__(1.0, 3), float.__floordiv__(float(3), 1.0))
416
417 def test_dunder_rfloordiv_returns_same_result_as_floordiv_for_float_other(self):
418 self.assertEqual(float.__rfloordiv__(1.0, 3.25), float.__floordiv__(3.25, 1.0))
419
420 def test_dunder_rmod_raises_type_error(self):
421 with self.assertRaises(TypeError):
422 float.__rmod__(1, 1.0)
423
424 def test_dunder_rmod__with_non_number_as_other_returns_not_implemented(self):
425 self.assertIs(float.__rmod__(1.0, "1"), NotImplemented)
426
427 def test_dunder_rmod_with_int_returns_same_result_as_mod_with_reversed_args(self):
428 self.assertEqual(float.__rmod__(1.0, 3), float.__mod__(float(3), 1.0))
429
430 def test_dunder_rmod_returns_same_result_as_mod_for_float_other(self):
431 self.assertEqual(float.__rmod__(1.0, 3.25), float.__mod__(3.25, 1.0))
432
433 def test_dunder_round_with_one_arg_returns_int(self):
434 self.assertEqual(float.__round__(0.0), 0)
435 self.assertIsInstance(float.__round__(0.0), int)
436 self.assertEqual(float.__round__(-0.0), 0)
437 self.assertIsInstance(float.__round__(-0.0), int)
438 self.assertEqual(float.__round__(1.0), 1)
439 self.assertIsInstance(float.__round__(1.0), int)
440 self.assertEqual(float.__round__(-1.0), -1)
441 self.assertIsInstance(float.__round__(-1.0), int)
442 self.assertEqual(float.__round__(42.42), 42)
443 self.assertIsInstance(float.__round__(42.42), int)
444 self.assertEqual(float.__round__(0.4), 0)
445 self.assertEqual(float.__round__(0.5), 0)
446 self.assertEqual(float.__round__(0.5000000000000001), 1)
447 self.assertEqual(float.__round__(1.49), 1)
448 self.assertEqual(float.__round__(1.5), 2)
449 self.assertEqual(float.__round__(1.5000000000000001), 2)
450 self.assertEqual(
451 float.__round__(1.234567e200),
452 123456699999999995062622360556161455756457158443485858665105941107312145749402909576243454437530421952327149599911208391362816498839992520580209467560546813973197632314335145381120371005964774514098176, # noqa: B950
453 )
454 self.assertEqual(float.__round__(-13.4, None), -13)
455 self.assertIsInstance(float.__round__(-13.4, None), int)
456
457 def test_dunder_round_with_float_subclass_returns_int(self):
458 class C(float):
459 pass
460
461 self.assertEqual(float.__round__(C(-7654321.7654321)), -7654322)
462
463 def test_dunder_round_with_one_arg_raises_error(self):
464 with self.assertRaises(ValueError) as context:
465 float.__round__(float("nan"))
466 self.assertEqual(str(context.exception), "cannot convert float NaN to integer")
467 with self.assertRaises(OverflowError) as context:
468 float.__round__(float("inf"))
469 self.assertEqual(
470 str(context.exception), "cannot convert float infinity to integer"
471 )
472 with self.assertRaises(OverflowError) as context:
473 float.__round__(float("-inf"))
474 self.assertEqual(
475 str(context.exception), "cannot convert float infinity to integer"
476 )
477
478 def test_dunder_round_with_two_args_returns_float(self):
479 self.assertEqual(float.__round__(0.0, 0), 0.0)
480 self.assertIsInstance(float.__round__(0.0, 0), float)
481 self.assertEqual(float.__round__(-0.0, 1), 0.0)
482 self.assertIsInstance(float.__round__(-0.0, 1), float)
483 self.assertEqual(float.__round__(1.0, 0), 1.0)
484 self.assertIsInstance(float.__round__(1.0, 0), float)
485 self.assertEqual(float.__round__(-77441.7, -2), -77400.0)
486 self.assertIsInstance(float.__round__(-77441.7, -2), float)
487
488 self.assertEqual(float.__round__(12.34567, -(1 << 200)), 0.0)
489 self.assertEqual(float.__round__(12.34567, -50), 0.0)
490 self.assertEqual(float.__round__(12.34567, -2), 0.0)
491 self.assertEqual(float.__round__(12.34567, -1), 10.0)
492 self.assertEqual(float.__round__(12.34567, 0), 12.0)
493 self.assertEqual(float.__round__(12.34567, 1), 12.3)
494 self.assertEqual(float.__round__(12.34567, 2), 12.35)
495 self.assertEqual(float.__round__(12.34567, 3), 12.346)
496 self.assertEqual(float.__round__(12.34567, 4), 12.3457)
497 self.assertEqual(float.__round__(12.34567, 50), 12.34567)
498 self.assertEqual(float.__round__(12.34567, 1 << 200), 12.34567)
499
500 self.assertEqual(float("inf"), float("inf"))
501 self.assertEqual(float("-inf"), -float("inf"))
502
503 float_max = 1.7976931348623157e308
504 self.assertEqual(float.__round__(float_max, -309), 0.0)
505 self.assertEqual(float.__round__(float_max, -303), 1.79769e308)
506
507 def test_dunder_round_with_two_args_returns_nan(self):
508 import math
509
510 self.assertTrue(math.isnan(float.__round__(float("nan"), 2)))
511
512 def test_dunder_round_with_two_args_raises_error(self):
513 float_max = 1.7976931348623157e308
514 with self.assertRaises(OverflowError) as context:
515 float.__round__(float_max, -308)
516 self.assertEqual(str(context.exception), "rounded value too large to represent")
517
518 def test_dunder_rpow_with_non_float_raises_type_error(self):
519 with self.assertRaises(TypeError):
520 float.__rpow__(None, 2.0)
521
522 def test_dunder_rpow_with_float_float_returns_result_from_pow_with_swapped_args(
523 self,
524 ):
525 self.assertEqual(float.__rpow__(2.0, 5.0), float.__pow__(5.0, 2.0))
526
527 def test_dunder_rpow_with_float_int_returns_result_from_pow_with_swapped_args(self):
528 result = float.__rpow__(2.0, 5)
529 self.assertIsInstance(result, float)
530 self.assertEqual(result, float.__pow__(5.0, 2.0))
531
532 def test_dunder_rpow_with_third_arg_int_raises_type_error(self):
533 with self.assertRaises(TypeError) as context:
534 float.__rpow__(2.0, 4.0, 4.0)
535 self.assertIn(
536 "pow() 3rd argument not allowed unless all arguments are integers",
537 str(context.exception),
538 )
539
540 def test_dunder_sub_with_non_float_raises_type_error(self):
541 self.assertRaisesRegex(
542 TypeError,
543 "'__sub__' .* 'float' object.* a 'int'",
544 float.__sub__,
545 2,
546 2.0,
547 )
548
549 def test_dunder_trunc_returns_int(self):
550 self.assertEqual(float.__trunc__(0.0), 0)
551 self.assertEqual(float.__trunc__(-0.0), 0)
552 self.assertEqual(float.__trunc__(1.0), 1)
553 self.assertEqual(float.__trunc__(-1.0), -1)
554 self.assertEqual(float.__trunc__(42.12345), 42)
555 self.assertEqual(float.__trunc__(1.6069380442589903e60), 1 << 200)
556 self.assertEqual(float.__trunc__(1e-20), 0)
557 self.assertEqual(float.__trunc__(-1e-20), 0)
558 self.assertIsInstance(float.__trunc__(0.0), int)
559 self.assertIsInstance(float.__trunc__(1.6069380442589903e60), int)
560 self.assertIsInstance(float.__trunc__(1e-20), int)
561
562 def test_dunder_trunc_raises_value_error(self):
563 with self.assertRaises(ValueError) as context:
564 float.__trunc__(float("nan"))
565 self.assertEqual(str(context.exception), "cannot convert float NaN to integer")
566 with self.assertRaises(OverflowError) as context:
567 float.__trunc__(float("inf"))
568 self.assertEqual(
569 str(context.exception), "cannot convert float infinity to integer"
570 )
571 with self.assertRaises(OverflowError) as context:
572 float.__trunc__(float("-inf"))
573 self.assertEqual(
574 str(context.exception), "cannot convert float infinity to integer"
575 )
576
577 def test_hex_with_positive_zero_returns_positive_zero(self):
578 self.assertEqual(float(0).hex(), "0x0.0p+0")
579
580 def test_hex_with_negative_zero_returns_negative_zero(self):
581 self.assertEqual(float(-0.0).hex(), "-0x0.0p+0")
582
583 def test_hex_with_positive_infinite_returns_inf(self):
584 self.assertEqual(float("inf").hex(), "inf")
585
586 def test_hex_with_negative_infinite_returns_minus_inf(self):
587 self.assertEqual(float("-inf").hex(), "-inf")
588
589 def test_hex_with_nan_returns_nan(self):
590 self.assertEqual(float("nan").hex(), "nan")
591
592 def test_hex_with_positive_decimal_returns_hex_string(self):
593 self.assertEqual(float(3.14159).hex(), "0x1.921f9f01b866ep+1")
594
595 def test_hex_with_negative_decimal_returns_hex_string(self):
596 self.assertEqual(float(-0.1).hex(), "-0x1.999999999999ap-4")
597
598 def test_hex_with_string_raises_type_error(self):
599 with self.assertRaises(TypeError):
600 float.hex("")
601
602 def test_as_integer_ratio_with_non_float_raises_type_error(self):
603 with self.assertRaises(TypeError):
604 float.as_integer_ratio(4)
605
606 def test_as_integer_ratio_with_infinity_raises_overflow_error(self):
607 inf = float("inf")
608 with self.assertRaises(OverflowError):
609 float.as_integer_ratio(inf)
610
611 def test_as_integer_ratio_with_nan_raises_value_error(self):
612 nan = float("nan")
613 with self.assertRaises(ValueError):
614 float.as_integer_ratio(nan)
615
616 def test_as_integer_ratio_with_integer_returns_denominator_one(self):
617 result = float.as_integer_ratio(10.0)
618 self.assertIs(type(result), tuple)
619 self.assertEqual(result, (10, 1))
620
621 def test_as_integer_ratio_with_zero_returns_denominator_one(self):
622 result = float.as_integer_ratio(0.0)
623 self.assertIs(type(result), tuple)
624 self.assertEqual(result, (0, 1))
625
626 def test_as_integer_ratio_with_negative_zero_returns_denominator_one(self):
627 result = float.as_integer_ratio(-0.0)
628 self.assertIs(type(result), tuple)
629 self.assertEqual(result, (-0, 1))
630
631 def test_as_integer_ratio_with_negative_integer_returns_negative_numerator(self):
632 result = float.as_integer_ratio(-0.25)
633 self.assertIs(type(result), tuple)
634 self.assertEqual(result, (-1, 4))
635
636 def test_as_integer_ratio_ignores_dunder_float(self):
637 class C(float):
638 def __float__(self):
639 return 0.25
640
641 result = float.as_integer_ratio(C(3.0))
642 self.assertIs(type(result), tuple)
643 self.assertEqual(result, (3, 1))
644
645 def test_as_integer_ratio_with_close_value(self):
646 result = float.as_integer_ratio(-1.000000000000001)
647 self.assertIs(type(result), tuple)
648 self.assertEqual(result, (-0x10000000000005, 0x10000000000000))
649
650 def test_is_integer_with_positive_zero_returns_true(self):
651 self.assertEqual((0.0).is_integer(), True)
652
653 def test_is_integer_with_negative_zero_returns_true(self):
654 self.assertEqual((-0.0).is_integer(), True)
655
656 def test_is_integer_with_positive_infinite_returns_false(self):
657 self.assertEqual(float("inf").is_integer(), False)
658
659 def test_is_integer_with_negative_infinite_returns_false(self):
660 self.assertEqual(float("-inf").is_integer(), False)
661
662 def test_is_integer_with_nan_returns_false(self):
663 self.assertEqual(float("nan").is_integer(), False)
664
665 def test_is_integer_with_positive_integer_returns_true(self):
666 self.assertEqual((3.0).is_integer(), True)
667
668 def test_is_integer_with_positive_non_integer_returns_false(self):
669 self.assertEqual((2.71828).is_integer(), False)
670
671 def test_is_integer_with_negative_integer_returns_true(self):
672 self.assertEqual((-1.0).is_integer(), True)
673
674 def test_is_integer_with_negative_non_integer_returns_false(self):
675 self.assertEqual((-3.14159).is_integer(), False)
676
677 def test_is_integer_with_close_value_returns_false(self):
678 self.assertEqual((-1.000000000000001).is_integer(), False)
679
680 def test_is_integer_with_string_raises_type_error(self):
681 with self.assertRaises(TypeError):
682 float.is_integer("")
683
684 def test_is_integer_with_float_subclass_integer_returns_true(self):
685 class C(float):
686 pass
687
688 self.assertEqual(C(10.0).is_integer(), True)
689
690 def test_is_integer_with_float_subclass_non_integer_returns_false(self):
691 class C(float):
692 pass
693
694 self.assertEqual(C(10.1).is_integer(), False)
695
696 def test_is_integer_with_float_multiple_inheritance_integer_returns_true(self):
697 class NotAfloat:
698 pass
699
700 class Afloat(float):
701 pass
702
703 class TreadingWater(Afloat, NotAfloat):
704 pass
705
706 self.assertEqual(TreadingWater(10.0).is_integer(), True)
707
708 def test_is_integer_with_float_nonsubclass_raises_type_error(self):
709 class NotAFloat:
710 pass
711
712 with self.assertRaises(TypeError):
713 float.is_integer(NotAFloat())
714
715 def test_float_with_str_trims_whitespace(self):
716 self.assertEqual(float("\t 14.2\n"), 14.2)
717 self.assertEqual(float("\t 14"), 14.0)
718 self.assertEqual(float(" 14.21 "), 14.21)
719 self.assertEqual(float("1 "), 1.0)
720 with self.assertRaises(ValueError):
721 float(" 14.2.1 ")
722 with self.assertRaises(ValueError):
723 float("")
724
725 def test_float_with_bytes_trims_whitespace(self):
726 self.assertEqual(float(b"\t 14.2\n"), 14.2)
727 self.assertEqual(float(b" 14.21 "), 14.21)
728
729 def test_float_hex_returns_str(self):
730 """This fuzzes the sign, exponent and mantissa fields
731 to interesting values (0, 1, +-1 near the bias/rollover point, max-1, max).
732 This helps ensure that floats near behavior changes (particularly at the
733 at subnormal->normal boundary) encode to hex correctly."""
734
735 self.assertEqual((0.0).hex(), "0x0.0p+0") # as_uint64_t: 0x0000000000000000
736 self.assertEqual(
737 (5e-324).hex(), "0x0.0000000000001p-1022"
738 ) # as_uint64_t: 0x0000000000000001
739 self.assertEqual(
740 (1.1125369292535997e-308).hex(), "0x0.7fffffffffffep-1022"
741 ) # as_uint64_t: 0x0007fffffffffffe
742 self.assertEqual(
743 (1.1125369292536e-308).hex(), "0x0.7ffffffffffffp-1022"
744 ) # as_uint64_t: 0x0007ffffffffffff
745 self.assertEqual(
746 (1.1125369292536007e-308).hex(), "0x0.8000000000000p-1022"
747 ) # as_uint64_t: 0x0008000000000000
748 self.assertEqual(
749 (1.112536929253601e-308).hex(), "0x0.8000000000001p-1022"
750 ) # as_uint64_t: 0x0008000000000001
751 self.assertEqual(
752 (2.2250738585072004e-308).hex(), "0x0.ffffffffffffep-1022"
753 ) # as_uint64_t: 0x000ffffffffffffe
754 self.assertEqual(
755 (2.225073858507201e-308).hex(), "0x0.fffffffffffffp-1022"
756 ) # as_uint64_t: 0x000fffffffffffff
757 self.assertEqual(
758 (2.2250738585072014e-308).hex(), "0x1.0000000000000p-1022"
759 ) # as_uint64_t: 0x0010000000000000
760 self.assertEqual(
761 (2.225073858507202e-308).hex(), "0x1.0000000000001p-1022"
762 ) # as_uint64_t: 0x0010000000000001
763 self.assertEqual(
764 (3.337610787760801e-308).hex(), "0x1.7fffffffffffep-1022"
765 ) # as_uint64_t: 0x0017fffffffffffe
766 self.assertEqual(
767 (3.3376107877608016e-308).hex(), "0x1.7ffffffffffffp-1022"
768 ) # as_uint64_t: 0x0017ffffffffffff
769 self.assertEqual(
770 (3.337610787760802e-308).hex(), "0x1.8000000000000p-1022"
771 ) # as_uint64_t: 0x0018000000000000
772 self.assertEqual(
773 (3.3376107877608026e-308).hex(), "0x1.8000000000001p-1022"
774 ) # as_uint64_t: 0x0018000000000001
775 self.assertEqual(
776 (4.450147717014402e-308).hex(), "0x1.ffffffffffffep-1022"
777 ) # as_uint64_t: 0x001ffffffffffffe
778 self.assertEqual(
779 (4.4501477170144023e-308).hex(), "0x1.fffffffffffffp-1022"
780 ) # as_uint64_t: 0x001fffffffffffff
781 self.assertEqual(
782 (4.450147717014403e-308).hex(), "0x1.0000000000000p-1021"
783 ) # as_uint64_t: 0x0020000000000000
784 self.assertEqual(
785 (4.450147717014404e-308).hex(), "0x1.0000000000001p-1021"
786 ) # as_uint64_t: 0x0020000000000001
787 self.assertEqual(
788 (6.675221575521602e-308).hex(), "0x1.7fffffffffffep-1021"
789 ) # as_uint64_t: 0x0027fffffffffffe
790 self.assertEqual(
791 (6.675221575521603e-308).hex(), "0x1.7ffffffffffffp-1021"
792 ) # as_uint64_t: 0x0027ffffffffffff
793 self.assertEqual(
794 (6.675221575521604e-308).hex(), "0x1.8000000000000p-1021"
795 ) # as_uint64_t: 0x0028000000000000
796 self.assertEqual(
797 (6.675221575521605e-308).hex(), "0x1.8000000000001p-1021"
798 ) # as_uint64_t: 0x0028000000000001
799 self.assertEqual(
800 (8.900295434028804e-308).hex(), "0x1.ffffffffffffep-1021"
801 ) # as_uint64_t: 0x002ffffffffffffe
802 self.assertEqual(
803 (8.900295434028805e-308).hex(), "0x1.fffffffffffffp-1021"
804 ) # as_uint64_t: 0x002fffffffffffff
805 self.assertEqual(
806 (0.5).hex(), "0x1.0000000000000p-1"
807 ) # as_uint64_t: 0x3fe0000000000000
808 self.assertEqual(
809 (0.5000000000000001).hex(), "0x1.0000000000001p-1"
810 ) # as_uint64_t: 0x3fe0000000000001
811 self.assertEqual(
812 (0.7499999999999998).hex(), "0x1.7fffffffffffep-1"
813 ) # as_uint64_t: 0x3fe7fffffffffffe
814 self.assertEqual(
815 (0.7499999999999999).hex(), "0x1.7ffffffffffffp-1"
816 ) # as_uint64_t: 0x3fe7ffffffffffff
817 self.assertEqual(
818 (0.75).hex(), "0x1.8000000000000p-1"
819 ) # as_uint64_t: 0x3fe8000000000000
820 self.assertEqual(
821 (0.7500000000000001).hex(), "0x1.8000000000001p-1"
822 ) # as_uint64_t: 0x3fe8000000000001
823 self.assertEqual(
824 (0.9999999999999998).hex(), "0x1.ffffffffffffep-1"
825 ) # as_uint64_t: 0x3feffffffffffffe
826 self.assertEqual(
827 (0.9999999999999999).hex(), "0x1.fffffffffffffp-1"
828 ) # as_uint64_t: 0x3fefffffffffffff
829 self.assertEqual(
830 (1.0).hex(), "0x1.0000000000000p+0"
831 ) # as_uint64_t: 0x3ff0000000000000
832 self.assertEqual(
833 (1.0000000000000002).hex(), "0x1.0000000000001p+0"
834 ) # as_uint64_t: 0x3ff0000000000001
835 self.assertEqual(
836 (1.4999999999999996).hex(), "0x1.7fffffffffffep+0"
837 ) # as_uint64_t: 0x3ff7fffffffffffe
838 self.assertEqual(
839 (1.4999999999999998).hex(), "0x1.7ffffffffffffp+0"
840 ) # as_uint64_t: 0x3ff7ffffffffffff
841 self.assertEqual(
842 (1.5).hex(), "0x1.8000000000000p+0"
843 ) # as_uint64_t: 0x3ff8000000000000
844 self.assertEqual(
845 (1.5000000000000002).hex(), "0x1.8000000000001p+0"
846 ) # as_uint64_t: 0x3ff8000000000001
847 self.assertEqual(
848 (1.9999999999999996).hex(), "0x1.ffffffffffffep+0"
849 ) # as_uint64_t: 0x3ffffffffffffffe
850 self.assertEqual(
851 (1.9999999999999998).hex(), "0x1.fffffffffffffp+0"
852 ) # as_uint64_t: 0x3fffffffffffffff
853 self.assertEqual(
854 (2.0).hex(), "0x1.0000000000000p+1"
855 ) # as_uint64_t: 0x4000000000000000
856 self.assertEqual(
857 (2.0000000000000004).hex(), "0x1.0000000000001p+1"
858 ) # as_uint64_t: 0x4000000000000001
859 self.assertEqual(
860 (2.999999999999999).hex(), "0x1.7fffffffffffep+1"
861 ) # as_uint64_t: 0x4007fffffffffffe
862 self.assertEqual(
863 (2.9999999999999996).hex(), "0x1.7ffffffffffffp+1"
864 ) # as_uint64_t: 0x4007ffffffffffff
865 self.assertEqual(
866 (3.0).hex(), "0x1.8000000000000p+1"
867 ) # as_uint64_t: 0x4008000000000000
868 self.assertEqual(
869 (3.0000000000000004).hex(), "0x1.8000000000001p+1"
870 ) # as_uint64_t: 0x4008000000000001
871 self.assertEqual(
872 (3.999999999999999).hex(), "0x1.ffffffffffffep+1"
873 ) # as_uint64_t: 0x400ffffffffffffe
874 self.assertEqual(
875 (3.9999999999999996).hex(), "0x1.fffffffffffffp+1"
876 ) # as_uint64_t: 0x400fffffffffffff
877 self.assertEqual(
878 (8.98846567431158e307).hex(), "0x1.0000000000000p+1023"
879 ) # as_uint64_t: 0x7fe0000000000000
880 self.assertEqual(
881 (8.988465674311582e307).hex(), "0x1.0000000000001p+1023"
882 ) # as_uint64_t: 0x7fe0000000000001
883 self.assertEqual(
884 (1.3482698511467365e308).hex(), "0x1.7fffffffffffep+1023"
885 ) # as_uint64_t: 0x7fe7fffffffffffe
886 self.assertEqual(
887 (1.3482698511467367e308).hex(), "0x1.7ffffffffffffp+1023"
888 ) # as_uint64_t: 0x7fe7ffffffffffff
889 self.assertEqual(
890 (1.348269851146737e308).hex(), "0x1.8000000000000p+1023"
891 ) # as_uint64_t: 0x7fe8000000000000
892 self.assertEqual(
893 (1.3482698511467371e308).hex(), "0x1.8000000000001p+1023"
894 ) # as_uint64_t: 0x7fe8000000000001
895 self.assertEqual(
896 (1.7976931348623155e308).hex(), "0x1.ffffffffffffep+1023"
897 ) # as_uint64_t: 0x7feffffffffffffe
898 self.assertEqual(
899 (1.7976931348623157e308).hex(), "0x1.fffffffffffffp+1023"
900 ) # as_uint64_t: 0x7fefffffffffffff
901 self.assertEqual((-0.0).hex(), "-0x0.0p+0") # as_uint64_t: 0x8000000000000000
902 self.assertEqual(
903 (-5e-324).hex(), "-0x0.0000000000001p-1022"
904 ) # as_uint64_t: 0x8000000000000001
905 self.assertEqual(
906 (-1.1125369292535997e-308).hex(), "-0x0.7fffffffffffep-1022"
907 ) # as_uint64_t: 0x8007fffffffffffe
908 self.assertEqual(
909 (-1.1125369292536e-308).hex(), "-0x0.7ffffffffffffp-1022"
910 ) # as_uint64_t: 0x8007ffffffffffff
911 self.assertEqual(
912 (-1.1125369292536007e-308).hex(), "-0x0.8000000000000p-1022"
913 ) # as_uint64_t: 0x8008000000000000
914 self.assertEqual(
915 (-1.112536929253601e-308).hex(), "-0x0.8000000000001p-1022"
916 ) # as_uint64_t: 0x8008000000000001
917 self.assertEqual(
918 (-2.2250738585072004e-308).hex(), "-0x0.ffffffffffffep-1022"
919 ) # as_uint64_t: 0x800ffffffffffffe
920 self.assertEqual(
921 (-2.225073858507201e-308).hex(), "-0x0.fffffffffffffp-1022"
922 ) # as_uint64_t: 0x800fffffffffffff
923 self.assertEqual(
924 (-2.2250738585072014e-308).hex(), "-0x1.0000000000000p-1022"
925 ) # as_uint64_t: 0x8010000000000000
926 self.assertEqual(
927 (-2.225073858507202e-308).hex(), "-0x1.0000000000001p-1022"
928 ) # as_uint64_t: 0x8010000000000001
929 self.assertEqual(
930 (-3.337610787760801e-308).hex(), "-0x1.7fffffffffffep-1022"
931 ) # as_uint64_t: 0x8017fffffffffffe
932 self.assertEqual(
933 (-3.3376107877608016e-308).hex(), "-0x1.7ffffffffffffp-1022"
934 ) # as_uint64_t: 0x8017ffffffffffff
935 self.assertEqual(
936 (-3.337610787760802e-308).hex(), "-0x1.8000000000000p-1022"
937 ) # as_uint64_t: 0x8018000000000000
938 self.assertEqual(
939 (-3.3376107877608026e-308).hex(), "-0x1.8000000000001p-1022"
940 ) # as_uint64_t: 0x8018000000000001
941 self.assertEqual(
942 (-4.450147717014402e-308).hex(), "-0x1.ffffffffffffep-1022"
943 ) # as_uint64_t: 0x801ffffffffffffe
944 self.assertEqual(
945 (-4.4501477170144023e-308).hex(), "-0x1.fffffffffffffp-1022"
946 ) # as_uint64_t: 0x801fffffffffffff
947 self.assertEqual(
948 (-4.450147717014403e-308).hex(), "-0x1.0000000000000p-1021"
949 ) # as_uint64_t: 0x8020000000000000
950 self.assertEqual(
951 (-4.450147717014404e-308).hex(), "-0x1.0000000000001p-1021"
952 ) # as_uint64_t: 0x8020000000000001
953 self.assertEqual(
954 (-6.675221575521602e-308).hex(), "-0x1.7fffffffffffep-1021"
955 ) # as_uint64_t: 0x8027fffffffffffe
956 self.assertEqual(
957 (-6.675221575521603e-308).hex(), "-0x1.7ffffffffffffp-1021"
958 ) # as_uint64_t: 0x8027ffffffffffff
959 self.assertEqual(
960 (-6.675221575521604e-308).hex(), "-0x1.8000000000000p-1021"
961 ) # as_uint64_t: 0x8028000000000000
962 self.assertEqual(
963 (-6.675221575521605e-308).hex(), "-0x1.8000000000001p-1021"
964 ) # as_uint64_t: 0x8028000000000001
965 self.assertEqual(
966 (-8.900295434028804e-308).hex(), "-0x1.ffffffffffffep-1021"
967 ) # as_uint64_t: 0x802ffffffffffffe
968 self.assertEqual(
969 (-8.900295434028805e-308).hex(), "-0x1.fffffffffffffp-1021"
970 ) # as_uint64_t: 0x802fffffffffffff
971 self.assertEqual(
972 (-0.5).hex(), "-0x1.0000000000000p-1"
973 ) # as_uint64_t: 0xbfe0000000000000
974 self.assertEqual(
975 (-0.5000000000000001).hex(), "-0x1.0000000000001p-1"
976 ) # as_uint64_t: 0xbfe0000000000001
977 self.assertEqual(
978 (-0.7499999999999998).hex(), "-0x1.7fffffffffffep-1"
979 ) # as_uint64_t: 0xbfe7fffffffffffe
980 self.assertEqual(
981 (-0.7499999999999999).hex(), "-0x1.7ffffffffffffp-1"
982 ) # as_uint64_t: 0xbfe7ffffffffffff
983 self.assertEqual(
984 (-0.75).hex(), "-0x1.8000000000000p-1"
985 ) # as_uint64_t: 0xbfe8000000000000
986 self.assertEqual(
987 (-0.7500000000000001).hex(), "-0x1.8000000000001p-1"
988 ) # as_uint64_t: 0xbfe8000000000001
989 self.assertEqual(
990 (-0.9999999999999998).hex(), "-0x1.ffffffffffffep-1"
991 ) # as_uint64_t: 0xbfeffffffffffffe
992 self.assertEqual(
993 (-0.9999999999999999).hex(), "-0x1.fffffffffffffp-1"
994 ) # as_uint64_t: 0xbfefffffffffffff
995 self.assertEqual(
996 (-1.0).hex(), "-0x1.0000000000000p+0"
997 ) # as_uint64_t: 0xbff0000000000000
998 self.assertEqual(
999 (-1.0000000000000002).hex(), "-0x1.0000000000001p+0"
1000 ) # as_uint64_t: 0xbff0000000000001
1001 self.assertEqual(
1002 (-1.4999999999999996).hex(), "-0x1.7fffffffffffep+0"
1003 ) # as_uint64_t: 0xbff7fffffffffffe
1004 self.assertEqual(
1005 (-1.4999999999999998).hex(), "-0x1.7ffffffffffffp+0"
1006 ) # as_uint64_t: 0xbff7ffffffffffff
1007 self.assertEqual(
1008 (-1.5).hex(), "-0x1.8000000000000p+0"
1009 ) # as_uint64_t: 0xbff8000000000000
1010 self.assertEqual(
1011 (-1.5000000000000002).hex(), "-0x1.8000000000001p+0"
1012 ) # as_uint64_t: 0xbff8000000000001
1013 self.assertEqual(
1014 (-1.9999999999999996).hex(), "-0x1.ffffffffffffep+0"
1015 ) # as_uint64_t: 0xbffffffffffffffe
1016 self.assertEqual(
1017 (-1.9999999999999998).hex(), "-0x1.fffffffffffffp+0"
1018 ) # as_uint64_t: 0xbfffffffffffffff
1019 self.assertEqual(
1020 (-2.0).hex(), "-0x1.0000000000000p+1"
1021 ) # as_uint64_t: 0xc000000000000000
1022 self.assertEqual(
1023 (-2.0000000000000004).hex(), "-0x1.0000000000001p+1"
1024 ) # as_uint64_t: 0xc000000000000001
1025 self.assertEqual(
1026 (-2.999999999999999).hex(), "-0x1.7fffffffffffep+1"
1027 ) # as_uint64_t: 0xc007fffffffffffe
1028 self.assertEqual(
1029 (-2.9999999999999996).hex(), "-0x1.7ffffffffffffp+1"
1030 ) # as_uint64_t: 0xc007ffffffffffff
1031 self.assertEqual(
1032 (-3.0).hex(), "-0x1.8000000000000p+1"
1033 ) # as_uint64_t: 0xc008000000000000
1034 self.assertEqual(
1035 (-3.0000000000000004).hex(), "-0x1.8000000000001p+1"
1036 ) # as_uint64_t: 0xc008000000000001
1037 self.assertEqual(
1038 (-3.999999999999999).hex(), "-0x1.ffffffffffffep+1"
1039 ) # as_uint64_t: 0xc00ffffffffffffe
1040 self.assertEqual(
1041 (-3.9999999999999996).hex(), "-0x1.fffffffffffffp+1"
1042 ) # as_uint64_t: 0xc00fffffffffffff
1043 self.assertEqual(
1044 (-8.98846567431158e307).hex(), "-0x1.0000000000000p+1023"
1045 ) # as_uint64_t: 0xffe0000000000000
1046 self.assertEqual(
1047 (-8.988465674311582e307).hex(), "-0x1.0000000000001p+1023"
1048 ) # as_uint64_t: 0xffe0000000000001
1049 self.assertEqual(
1050 (-1.3482698511467365e308).hex(), "-0x1.7fffffffffffep+1023"
1051 ) # as_uint64_t: 0xffe7fffffffffffe
1052 self.assertEqual(
1053 (-1.3482698511467367e308).hex(), "-0x1.7ffffffffffffp+1023"
1054 ) # as_uint64_t: 0xffe7ffffffffffff
1055 self.assertEqual(
1056 (-1.348269851146737e308).hex(), "-0x1.8000000000000p+1023"
1057 ) # as_uint64_t: 0xffe8000000000000
1058 self.assertEqual(
1059 (-1.3482698511467371e308).hex(), "-0x1.8000000000001p+1023"
1060 ) # as_uint64_t: 0xffe8000000000001
1061 self.assertEqual(
1062 (-1.7976931348623155e308).hex(), "-0x1.ffffffffffffep+1023"
1063 ) # as_uint64_t: 0xffeffffffffffffe
1064 self.assertEqual(
1065 (-1.7976931348623157e308).hex(), "-0x1.fffffffffffffp+1023"
1066 ) # as_uint64_t: 0xffefffffffffffff
1067
1068
1069class FloatDunderFormatTests(unittest.TestCase):
1070 def test_empty_format_returns_str(self):
1071 self.assertEqual(float.__format__(0.0, ""), "0.0")
1072 self.assertEqual(float.__format__(1.2, ""), "1.2")
1073 self.assertEqual(float.__format__(-1.6, ""), "-1.6")
1074 self.assertEqual(float("NaN").__format__(""), "nan")
1075 self.assertEqual(float("inf").__format__(""), "inf")
1076
1077 def test_empty_format_with_subclass_calls_dunder_str(self):
1078 class C(float):
1079 def __str__(self):
1080 return "foobar"
1081
1082 self.assertEqual(float.__format__(C(0.0), ""), "foobar")
1083 self.assertEqual(float.__format__(C("nan"), ""), "foobar")
1084 self.assertEqual(float.__format__(C("inf"), ""), "foobar")
1085
1086 def test_nonempty_format_with_subclass_uses_float_value(self):
1087 class C(float):
1088 def __str__(self):
1089 return "foobar"
1090
1091 self.assertEqual(float.__format__(C(0.0), "e"), "0.000000e+00")
1092 self.assertEqual(float.__format__(C("nan"), "F"), "NAN")
1093 self.assertEqual(float.__format__(C("inf"), "g"), "inf")
1094
1095 def test_e_format_returns_str(self):
1096 self.assertEqual(float.__format__(0.0, "e"), "0.000000e+00")
1097 self.assertEqual(float.__format__(-0.0, "e"), "-0.000000e+00")
1098 self.assertEqual(float.__format__(0.0025, "e"), "2.500000e-03")
1099 self.assertEqual(float.__format__(-1000.0001, "e"), "-1.000000e+03")
1100 self.assertEqual(float.__format__(2.0 ** 64, "e"), "1.844674e+19")
1101 self.assertEqual(float("NAN").__format__("e"), "nan")
1102 self.assertEqual(float("-INF").__format__("e"), "-inf")
1103
1104 def test_big_e_format_returns_str(self):
1105 self.assertEqual(float.__format__(0.0, "E"), "0.000000E+00")
1106 self.assertEqual(float.__format__(-0.0, "E"), "-0.000000E+00")
1107 self.assertEqual(float.__format__(0.0025, "E"), "2.500000E-03")
1108 self.assertEqual(float.__format__(-1000.0001, "E"), "-1.000000E+03")
1109 self.assertEqual(float.__format__(2.0 ** 64, "E"), "1.844674E+19")
1110 self.assertEqual(float("nan").__format__("E"), "NAN")
1111 self.assertEqual(float("-inf").__format__("E"), "-INF")
1112
1113 def test_f_format_returns_str(self):
1114 self.assertEqual(float.__format__(0.0, "f"), "0.000000")
1115 self.assertEqual(float.__format__(-0.0, "f"), "-0.000000")
1116 self.assertEqual(float.__format__(0.0025, "f"), "0.002500")
1117 self.assertEqual(float.__format__(-1000.0001, "f"), "-1000.000100")
1118 self.assertEqual(
1119 float.__format__(2.0 ** 64, "f"), "18446744073709551616.000000"
1120 )
1121 self.assertEqual(float("NaN").__format__("f"), "nan")
1122 self.assertEqual(float("INF").__format__("f"), "inf")
1123
1124 def test_big_f_format_returns_str(self):
1125 self.assertEqual(float.__format__(0.0, "F"), "0.000000")
1126 self.assertEqual(float.__format__(-0.0, "F"), "-0.000000")
1127 self.assertEqual(float.__format__(0.0025, "F"), "0.002500")
1128 self.assertEqual(float.__format__(-1000.0001, "F"), "-1000.000100")
1129 self.assertEqual(
1130 float.__format__(2.0 ** 64, "F"), "18446744073709551616.000000"
1131 )
1132 self.assertEqual(float("NaN").__format__("F"), "NAN")
1133 self.assertEqual(float("iNf").__format__("F"), "INF")
1134
1135 def test_g_format_returns_str(self):
1136 self.assertEqual(float.__format__(0.0, "g"), "0")
1137 self.assertEqual(float.__format__(-0.0, "g"), "-0")
1138 self.assertEqual(float.__format__(0.00025, "g"), "0.00025")
1139 self.assertEqual(float.__format__(0.000025, "g"), "2.5e-05")
1140 self.assertEqual(float.__format__(-1000.0001, "g"), "-1000")
1141 self.assertEqual(float.__format__(123456.789, "g"), "123457")
1142 self.assertEqual(float.__format__(1234567.89, "g"), "1.23457e+06")
1143 self.assertEqual(float.__format__(2.0 ** 64, "g"), "1.84467e+19")
1144 self.assertEqual(float("NaN").__format__("g"), "nan")
1145 self.assertEqual(float("INF").__format__("g"), "inf")
1146
1147 def test_big_g_format_returns_str(self):
1148 self.assertEqual(float.__format__(0.0, "G"), "0")
1149 self.assertEqual(float.__format__(-0.0, "G"), "-0")
1150 self.assertEqual(float.__format__(0.00025, "G"), "0.00025")
1151 self.assertEqual(float.__format__(0.000025, "G"), "2.5E-05")
1152 self.assertEqual(float.__format__(-1000.0001, "G"), "-1000")
1153 self.assertEqual(float.__format__(123456.789, "G"), "123457")
1154 self.assertEqual(float.__format__(1234567.89, "G"), "1.23457E+06")
1155 self.assertEqual(float.__format__(2.0 ** 64, "G"), "1.84467E+19")
1156 self.assertEqual(float("Nan").__format__("G"), "NAN")
1157 self.assertEqual(float("Inf").__format__("G"), "INF")
1158
1159 # TODO(T52759101): test 'n' uses locale
1160
1161 def test_percent_format_returns_str(self):
1162 self.assertEqual(float.__format__(0.0, "%"), "0.000000%")
1163 self.assertEqual(float.__format__(-0.0, "%"), "-0.000000%")
1164 self.assertEqual(float.__format__(0.0025, "%"), "0.250000%")
1165 self.assertEqual(float.__format__(-1000.0001, "%"), "-100000.010000%")
1166 self.assertEqual(float.__format__(2.0 ** 10, "%"), "102400.000000%")
1167 self.assertEqual(float("NaN").__format__("%"), "nan%")
1168 self.assertEqual(float("INF").__format__("%"), "inf%")
1169
1170 def test_missing_precision_raises_value_error(self):
1171 with self.assertRaises(ValueError) as context:
1172 float.__format__(0.0, ".f")
1173
1174 self.assertEqual("Format specifier missing precision", str(context.exception))
1175
1176 def test_large_integer_precision_raises_value_error(self):
1177 with self.assertRaises(ValueError) as context:
1178 float.__format__(0.0, ".2147483648f")
1179
1180 self.assertEqual("precision too big", str(context.exception))
1181
1182 def test_precision_determines_remainder_length(self):
1183 self.assertEqual(float.__format__(0.0, ".0e"), "0e+00")
1184 self.assertEqual(float.__format__(123.0, ".0E"), "1E+02")
1185 self.assertEqual(float.__format__(4.56, ".0f"), "5")
1186 self.assertEqual(float.__format__(78.9, ".0F"), "79")
1187 self.assertEqual(float.__format__(71.0, ".0g"), "7e+01")
1188 self.assertEqual(float.__format__(0.025, ".0G"), "0.03")
1189 self.assertEqual(float.__format__(0.005, ".0%"), "0%")
1190 self.assertEqual(float.__format__(0.0051, ".0%"), "1%")
1191
1192 self.assertEqual(float.__format__(-0.0, ".2e"), "-0.00e+00")
1193 self.assertEqual(float.__format__(123.0, ".1E"), "1.2E+02")
1194 self.assertEqual(float.__format__(4.56, ".10f"), "4.5600000000")
1195 self.assertEqual(float.__format__(0.00000000000789, ".8F"), "0.00000000")
1196 self.assertEqual(float.__format__(71.0, ".4g"), "71")
1197 self.assertEqual(float.__format__(0.000025, ".5G"), "2.5E-05")
1198 self.assertEqual(float.__format__(0.0005, ".4%"), "0.0500%")
1199
1200 self.assertEqual(float.__format__(123.456, ".4"), "123.5")
1201 self.assertEqual(float.__format__(1234.56, ".4"), "1.235e+03")
1202 self.assertEqual(float.__format__(12345.6, ".4"), "1.235e+04")
1203
1204 def test_grouping_by_thousands(self):
1205 self.assertEqual(float.__format__(12345678.9, "_e"), "1.234568e+07")
1206 self.assertEqual(float.__format__(123456.789, "_E"), "1.234568E+05")
1207 self.assertEqual(float.__format__(12345678.9, "_f"), "12_345_678.900000")
1208 self.assertEqual(float.__format__(123456.789, ",F"), "123,456.789000")
1209 self.assertEqual(float.__format__(12345678.9, ",g"), "1.23457e+07")
1210 self.assertEqual(float.__format__(123456.789, ",G"), "123,457")
1211 self.assertEqual(float.__format__(123456.789, "_%"), "12_345_678.900000%")
1212
1213 def test_padding(self):
1214 self.assertEqual(float.__format__(123.456, "3e"), "1.234560e+02")
1215 self.assertEqual(float.__format__(0.0123456789, ">11.4E"), " 1.2346E-02")
1216 self.assertEqual(float.__format__(0.0, "2f"), "0.000000")
1217 self.assertEqual(float.__format__(-0.0, "7.2F"), " -0.00")
1218 self.assertEqual(float("NaN").__format__("*^8g"), "**nan***")
1219 self.assertEqual(float.__format__(-10.02, "=8g"), "- 10.02")
1220 self.assertEqual(float.__format__(-1.234, "!<10G"), "-1.234!!!!")
1221
1222 def test_alternate_returns_str(self):
1223 self.assertEqual(float.__format__(0.0, "#"), "0.0")
1224 self.assertEqual(float.__format__(-123.00, "#.0e"), "-1.e+02")
1225 self.assertEqual(float.__format__(-0.123, "#.0E"), "-1.E-01")
1226 self.assertEqual(float.__format__(12.021, "#.2f"), "12.02")
1227 self.assertEqual(float.__format__(12.021, "#.0F"), "12.")
1228 self.assertEqual(float.__format__(12.0, "#g"), "12.0000")
1229 self.assertEqual(float.__format__(2.0 ** 63, "#.1G"), "9.E+18")
1230
1231 def test_with_sign_returns_str(self):
1232 self.assertEqual(float.__format__(1.0, " "), " 1.0")
1233 self.assertEqual(float.__format__(1.0, "+"), "+1.0")
1234 self.assertEqual(float.__format__(1.0, "-"), "1.0")
1235 self.assertEqual(float.__format__(-4.0, " "), "-4.0")
1236 self.assertEqual(float.__format__(-4.0, "+"), "-4.0")
1237 self.assertEqual(float.__format__(-4.0, "-"), "-4.0")
1238
1239 def test_sign_aware_zero_padding_allows_zero_width(self):
1240 self.assertEqual(float.__format__(123.0, "00"), "123.0")
1241 self.assertEqual(float.__format__(123.34, "00f"), "123.340000")
1242 self.assertEqual(float.__format__(123.34, "00e"), "1.233400e+02")
1243 self.assertEqual(float.__format__(123.34, "00g"), "123.34")
1244 self.assertEqual(float.__format__(123.34, "00.10f"), "123.3400000000")
1245 self.assertEqual(float.__format__(123.34, "00.10e"), "1.2334000000e+02")
1246 self.assertEqual(float.__format__(123.34, "00.10g"), "123.34")
1247 self.assertEqual(float.__format__(123.34, "01f"), "123.340000")
1248
1249 self.assertEqual(float.__format__(-123.0, "00"), "-123.0")
1250 self.assertEqual(float.__format__(-123.34, "00f"), "-123.340000")
1251 self.assertEqual(float.__format__(-123.34, "00e"), "-1.233400e+02")
1252 self.assertEqual(float.__format__(-123.34, "00g"), "-123.34")
1253 self.assertEqual(float.__format__(-123.34, "00.10f"), "-123.3400000000")
1254 self.assertEqual(float.__format__(-123.34, "00.10f"), "-123.3400000000")
1255 self.assertEqual(float.__format__(-123.34, "00.10e"), "-1.2334000000e+02")
1256 self.assertEqual(float.__format__(-123.34, "00.10g"), "-123.34")
1257
1258 def test_unknown_format_raises_value_error(self):
1259 with self.assertRaises(ValueError) as context:
1260 float.__format__(42.0, "c")
1261 self.assertEqual(
1262 str(context.exception), "Unknown format code 'c' for object of type 'float'"
1263 )
1264
1265 def test_with_non_float_raises_type_error(self):
1266 self.assertRaisesRegex(
1267 TypeError,
1268 "'__format__' .* 'float' object.* a 'int'",
1269 float.__format__,
1270 1,
1271 "",
1272 )
1273
1274 def test_with_underscore_between_digits_returns_float(self):
1275 self.assertEqual(float(2_3.5_3), 23.53)
1276
1277 def test_with_underscore_not_between_digits_raises_value_error(self):
1278 with self.assertRaises(ValueError) as context:
1279 float("_11")
1280 self.assertEqual(
1281 str(context.exception), "could not convert string to float: '_11'"
1282 )
1283 with self.assertRaises(ValueError) as context:
1284 float("4.4_")
1285 self.assertEqual(
1286 str(context.exception), "could not convert string to float: '4.4_'"
1287 )
1288 with self.assertRaises(ValueError) as context:
1289 float("2_3.5__3")
1290 self.assertEqual(
1291 str(context.exception), "could not convert string to float: '2_3.5__3'"
1292 )
1293 with self.assertRaises(ValueError) as context:
1294 float("4._4")
1295 self.assertEqual(
1296 str(context.exception), "could not convert string to float: '4._4'"
1297 )
1298
1299
1300if __name__ == "__main__":
1301 unittest.main()