Uh oh!
There was an error while loading. Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork 34k
bpo-39277, pytime: Fix overflow check on double to int cast#17933
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Uh oh!
There was an error while loading. Please reload this page.
Changes from all commits
File filter
Filter by extension
Conversations
Uh oh!
There was an error while loading. Please reload this page.
Jump to
Uh oh!
There was an error while loading. Please reload this page.
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -221,10 +221,27 @@ PyAPI_FUNC(void) _Py_set_387controlword(unsigned short); | ||
| #define _Py_IntegralTypeMax(type) ((_Py_IntegralTypeSigned(type)) ? (((((type)1 << (sizeof(type)*CHAR_BIT - 2)) - 1) << 1) + 1) : ~(type)0) | ||
| /* Return the minimum value of integral type *type*. */ | ||
| #define _Py_IntegralTypeMin(type) ((_Py_IntegralTypeSigned(type)) ? -_Py_IntegralTypeMax(type) - 1 : 0) | ||
| /* Check whether *v* is in the range of integral type *type*. This is most | ||
| * useful if *v* is floating-point, since demoting a floating-point *v* to an | ||
| * integral type that cannot represent *v*'s integral part is undefined | ||
| * behavior. */ | ||
| #define _Py_InIntegralTypeRange(type, v) (_Py_IntegralTypeMin(type) <= v && v <= _Py_IntegralTypeMax(type)) | ||
| /* Check if the floating-point number v (double) would overflow when casted to | ||
| * the integral type 'type'. | ||
| * | ||
| * Test (double)type_min(type) <= v <= (double)type_max(type) where v is a | ||
| * double, and type_min() and type_max() integers are rounded towards zero when | ||
| * casted to a double. | ||
| * | ||
| * (double)int cast rounds to nearest with ties going to nearest even integer | ||
| * (ROUND_HALF_EVEN). Use nextafter() to round towards zeros (ROUND_DOWN). | ||
| * | ||
| * For example, _Py_IntegralTypeMax(int64_t)=2**63-1 casted to double gives | ||
| * 2**63 which is greater than 2**63-1. The problem is that "v <= 2**63" fails | ||
| * to detect that v will overflow when casted to int64_t. | ||
| * nextafter((double)(2**63-1), 0.0) gives the floating-point number 2**63-1024 | ||
| * which is less than or equal to the integer 2**63-1 and so can be used to | ||
| * test that v would overflow. | ||
| * | ||
| * In short, nextafter((double)x, 0.0) rounds the integer x towards zero. */ | ||
| #define _Py_DoubleInIntegralTypeRange(type, v) \ | ||
| (nextafter((double)_Py_IntegralTypeMin(type), 0.0) <= v \ | ||
Member
| ||
| && v <= nextafter((double)_Py_IntegralTypeMax(type), 0.0)) | ||
| #endif /* Py_PYMATH_H */ | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,2 @@ | ||
| Fix :func:`time.sleep` to properly detect integer overflow when converting a | ||
| floating-point number of seconds to an integer. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The two conditions "v would overflow when cast to 'type'" and "type_MIN <= v <= type_MAX" are not equivalent. Which one do you want to test here?
For example, assuming a 32-bit
inttype:type_MAXwould be2147483647. Ifv = 2147483647.5(which is exactly representable in IEEE 754 binary64 floating-point), then it satisfies the first condition - it doesn't overflow when cast toint- but not the second.