|
| 1 | +import math |
1 | 2 | import sys
|
2 | 3 | import unittest
|
3 | 4 | from test.support import import_helper
|
@@ -77,3 +78,43 @@ def python_hash_pointer(x):
|
77 | 78 | # Py_HashPointer((void*)(uintptr_t)-1) doesn't return -1 but -2
|
78 | 79 | VOID_P_MAX = -1 & (2 ** (8 * SIZEOF_VOID_P) - 1)
|
79 | 80 | self.assertEqual(hash_pointer(VOID_P_MAX), -2)
|
| 81 | + |
| 82 | + def test_hash_double(self): |
| 83 | + # Test Py_HashDouble() |
| 84 | + hash_double = _testcapi.hash_double |
| 85 | + |
| 86 | + # test some integers |
| 87 | + integers = [ |
| 88 | + *range(1, 30), |
| 89 | + 2**30 - 1, |
| 90 | + 2 ** 233, |
| 91 | + int(sys.float_info.max), |
| 92 | + ] |
| 93 | + for x in integers: |
| 94 | + with self.subTest(x=x): |
| 95 | + self.assertEqual(hash_double(float(x)), hash(x)) |
| 96 | + self.assertEqual(hash_double(float(-x)), hash(-x)) |
| 97 | + |
| 98 | + # test positive and negative zeros |
| 99 | + self.assertEqual(hash_double(float(0.0)), 0) |
| 100 | + self.assertEqual(hash_double(float(-0.0)), 0) |
| 101 | + |
| 102 | + # test +inf and -inf |
| 103 | + inf = float("inf") |
| 104 | + self.assertEqual(hash_double(inf), sys.hash_info.inf) |
| 105 | + self.assertEqual(hash_double(-inf), -sys.hash_info.inf) |
| 106 | + |
| 107 | + # special float values: compare with Python hash() function |
| 108 | + special_values = ( |
| 109 | + math.nextafter(0.0, 1.0), # smallest positive subnormal number |
| 110 | + sys.float_info.min, # smallest positive normal number |
| 111 | + sys.float_info.epsilon, |
| 112 | + sys.float_info.max, # largest positive finite number |
| 113 | + ) |
| 114 | + for x in special_values: |
| 115 | + with self.subTest(x=x): |
| 116 | + self.assertEqual(hash_double(x), hash(x)) |
| 117 | + self.assertEqual(hash_double(-x), hash(-x)) |
| 118 | + |
| 119 | + # test not-a-number (NaN) |
| 120 | + self.assertEqual(hash_double(float('nan')), 0) |
0 commit comments