| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
Sorry, something went wrong.
Fix time.sleep() to properly detect integer overflow when converting a floating-point number of seconds to an integer.
| /* 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 |
There was a problem hiding this comment.
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 int type: type_MAX would be 2147483647. If v = 2147483647.5 (which is exactly representable in IEEE 754 binary64 floating-point), then it satisfies the first condition - it doesn't overflow when cast to int - but not the second.
Sorry, something went wrong.
| * | ||
| * 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 \ |
There was a problem hiding this comment.
Sorry, but this isn't right.
For a 32-bit signed integer type, this condition becomes:
-2147483647.9999998 <= v <= 2147483646.9999998
but what we actually want is:
-2147483649.0 < v < 2147483648.0
or if we want to use <= and express the limits in terms of doubles:
-2147483648.9999995 <= v <= 2147483647.9999998
For a 64-bit signed integer type, this condition becomes:
-9223372036854774784.0 <= v <= 9223372036854774784.0
but the actual limits we need are
-9223372036854775808.0 <= v <= 9223372036854774784.0
Sorry, something went wrong.
There was a problem hiding this comment.
Suggested alternative approach: given a double v that we want to safely convert to an int (say), first use modf to extract the fractional part fv and the integer part iv of v (both fv and iv are still doubles at this point). We can just ignore the fractional part fv: it doesn't affect whether we can safely cast to int or not. Now for iv, check whether it satisfies (double)INT_MIN <= iv and iv < -(double)INT_MIN. Note that INT_MIN is (always in practice, even though not guaranteed by the standard) the negation of a power of two, so the conversion to double doesn't change the value and we're effectively checking whether iv lies in the half-open interval [INT_MIN, -INT_MIN). Since iv is an integer, that's equivalent to checking whether iv lies in the closed interval [INT_MIN, -INT_MIN-1]. But making all our usual assumptions about integer representation (two's complement, no trap representation, no padding bits, etc.), -INT_MIN-1 is the same as INT_MAX, so we're effectively checking that the integer part of v is representable as an int, which is exactly what we want to be checking.
Similarly for long, long long, etc.
Sorry, something went wrong.
|
A safe way to do what you want is: (1) Take the integral part of the double v that you want to check, for example using modf, still represented as a double. (Note that the integral part of an IEEE 754 floating-point number is always exactly representable in the same format.) Computing TYPE_MAX + 1 while avoiding overflow may take some type-specific effort. The reason that step (2) is safe is that, making the fairly safe assumption of 2s complement (no trap representation, etc., etc.) for signed integers, TYPE_MIN and TYPE_MAX + 1 will always be exactly representable as a double (well, assuming that we're not dealing with 1024-bit integers, that is). But TYPE_MAX can't be assumed to be exactly representable as a double - whether it is or not will depend on the width of the type being tested. |
Sorry, something went wrong.
There was a problem hiding this comment.
This isn't the right way to check for convertibility; see the other comments I made on the PR.
Sorry, something went wrong.
|
When you're done making the requested changes, leave the comment: I have made the requested changes; please review again. And if you don't make the requested changes, you will be put in the comfy chair! |
Sorry, something went wrong.
|
I failed finding time to finish the PR. I prefer to abandon it. |
Sorry, something went wrong.
| Back | FazBrowse Home | New Git URL |
Fix time.sleep() to properly detect integer overflow when converting
a floating-point number of seconds to an integer.
https://bugs.python.org/issue39277