mirror of
https://github.com/python/cpython.git
synced 2025-12-08 06:10:17 +00:00
[3.14] gh-141042: fix sNaN's packing for mixed floating-point formats (GH-141107) (#141459)
gh-141042: fix sNaN's packing for mixed floating-point formats (GH-141107)
(cherry picked from commit 23d85a2a3f)
Co-authored-by: Sergey B Kirpichev <skirpichev@gmail.com>
This commit is contained in:
parent
75b5157e84
commit
e9c11b7495
3 changed files with 59 additions and 14 deletions
|
|
@ -2028,6 +2028,10 @@ PyFloat_Pack2(double x, char *data, int le)
|
|||
memcpy(&v, &x, sizeof(v));
|
||||
v &= 0xffc0000000000ULL;
|
||||
bits = (unsigned short)(v >> 42); /* NaN's type & payload */
|
||||
/* set qNaN if no payload */
|
||||
if (!bits) {
|
||||
bits |= (1<<9);
|
||||
}
|
||||
}
|
||||
else {
|
||||
sign = (x < 0.0);
|
||||
|
|
@ -2200,16 +2204,16 @@ PyFloat_Pack4(double x, char *data, int le)
|
|||
if ((v & (1ULL << 51)) == 0) {
|
||||
uint32_t u32;
|
||||
memcpy(&u32, &y, 4);
|
||||
u32 &= ~(1 << 22); /* make sNaN */
|
||||
/* if have payload, make sNaN */
|
||||
if (u32 & 0x3fffff) {
|
||||
u32 &= ~(1 << 22);
|
||||
}
|
||||
memcpy(&y, &u32, 4);
|
||||
}
|
||||
#else
|
||||
uint32_t u32;
|
||||
|
||||
memcpy(&u32, &y, 4);
|
||||
if ((v & (1ULL << 51)) == 0) {
|
||||
u32 &= ~(1 << 22);
|
||||
}
|
||||
/* Workaround RISC-V: "If a NaN value is converted to a
|
||||
* different floating-point type, the result is the
|
||||
* canonical NaN of the new type". The canonical NaN here
|
||||
|
|
@ -2220,6 +2224,10 @@ PyFloat_Pack4(double x, char *data, int le)
|
|||
/* add payload */
|
||||
u32 -= (u32 & 0x3fffff);
|
||||
u32 += (uint32_t)((v & 0x7ffffffffffffULL) >> 29);
|
||||
/* if have payload, make sNaN */
|
||||
if ((v & (1ULL << 51)) == 0 && (u32 & 0x3fffff)) {
|
||||
u32 &= ~(1 << 22);
|
||||
}
|
||||
|
||||
memcpy(&y, &u32, 4);
|
||||
#endif
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue