Skip to content

Commit 092d729

Browse files
committed
fixup value on win32
1 parent 3e5a211 commit 092d729

File tree

3 files changed

+51
-7
lines changed

3 files changed

+51
-7
lines changed

Lib/test/test_capi/test_float.py

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -183,25 +183,27 @@ def test_pack_unpack_roundtrip(self):
183183
def test_pack_unpack_roundtrip_for_nans(self):
184184
pack = _testcapi.float_pack
185185
unpack = _testcapi.float_unpack
186-
187-
for _ in range(100):
186+
for _ in range(1000):
188187
for size in (2, 4, 8):
189188
sign = random.randint(0, 1)
190-
quiet = random.randint(0, 1)
189+
signaling = random.randint(0, 1)
190+
quiet = int(not signaling)
191191
if size == 8:
192-
payload = random.randint(0 if quiet else 1, 1<<50)
192+
payload = random.randint(signaling, 1<<50)
193193
i = (sign<<63) + (0x7ff<<52) + (quiet<<51) + payload
194194
elif size == 4:
195-
payload = random.randint(0 if quiet else 1, 1<<21)
195+
payload = random.randint(signaling, 1<<21)
196196
i = (sign<<31) + (0xff<<23) + (quiet<<22) + payload
197197
elif size == 2:
198-
payload = random.randint(0 if quiet else 1, 1<<8)
198+
payload = random.randint(signaling, 1<<8)
199199
i = (sign<<15) + (0x1f<<10) + (quiet<<9) + payload
200200
data = bytes.fromhex(f'{i:x}')
201201
for endian in (BIG_ENDIAN, LITTLE_ENDIAN):
202202
with self.subTest(data=data, size=size, endian=endian):
203203
data1 = data if endian == BIG_ENDIAN else data[::-1]
204204
value = unpack(data1, endian)
205+
if signaling and sys.platform == 'win32':
206+
value = _testcapi.float_set_snan(value)
205207
data2 = pack(size, value, endian)
206208
self.assertTrue(math.isnan(value))
207209
self.assertEqual(data1, data2)

Modules/_testcapi/clinic/float.c.h

Lines changed: 10 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Modules/_testcapi/float.c

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,13 +157,46 @@ test_string_to_double(PyObject *self, PyObject *Py_UNUSED(ignored))
157157
}
158158

159159

160+
/*[clinic input]
161+
_testcapi.float_set_snan
162+
163+
obj: object
164+
/
165+
166+
Make a signaling NaN.
167+
[clinic start generated code]*/
168+
169+
static PyObject *
170+
_testcapi_float_set_snan(PyObject *module, PyObject *obj)
171+
/*[clinic end generated code: output=f43778a70f60aa4b input=c1269b0f88ef27ac]*/
172+
{
173+
if (!PyFloat_Check(obj)) {
174+
PyErr_SetString(PyExc_ValueError, "float-point number expected");
175+
return NULL;
176+
}
177+
PyObject *ret = PyNumber_Positive(obj);
178+
if (!ret) {
179+
return NULL;
180+
}
181+
double *d = &((PyFloatObject *)ret)->ob_fval;
182+
if (!isnan(*d)) {
183+
PyErr_SetString(PyExc_ValueError, "nan expected");
184+
return NULL;
185+
}
186+
uint64_t *v = (uint64_t *)d;
187+
*v &= ~(1ULL<<51); /* make sNaN */
188+
return ret;
189+
}
190+
160191
static PyMethodDef test_methods[] = {
161192
_TESTCAPI_FLOAT_PACK_METHODDEF
162193
_TESTCAPI_FLOAT_UNPACK_METHODDEF
194+
_TESTCAPI_FLOAT_SET_SNAN_METHODDEF
163195
{"test_string_to_double", test_string_to_double, METH_NOARGS},
164196
{NULL},
165197
};
166198

199+
167200
int
168201
_PyTestCapi_Init_Float(PyObject *mod)
169202
{

0 commit comments

Comments
 (0)