Repository navigation
Fix pow overflow checks at min_value - #201
Open
abhiishek340 wants to merge 1 commit into
Open
abhiishek340 wants to merge 1 commit into
abhiishek340 wants to merge 1 commit into
Conversation
The negative overflow bounds were the negated positive bounds, but min_value has one more unit of magnitude than max_value. As a result: - Int64.pow rejected exact results equal to Int64.min_value, such as (-2L) ** 63L and (-8L) ** 21L, and raised for Int64.min_value ** 0L. - Int.pow and the Int63-on-int64 path used [abs base], which is negative for min_value, so Int.pow Int.min_value 2 returned 0 instead of raising. They also rejected (-4) ** 31 = Int.min_value. Generate negative bounds from the minimum value for every integer type, and make int_pow and int63_pow_on_int64 compare signed bases against the positive and negative bounds, as int64_pow already does. Fixes janestreet#197 Signed-off-by: Abhishek Yadav <abhiishek340@gmail.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #197.
The negative overflow bounds were generated as the negated positive bounds, but
min_valuehas one more unit of magnitude thanmax_value. Separately,int_powandint63_pow_on_int64usedabs base, which is negative formin_value, so the bounds check was skipped.Int.pow Int.min_value 20Int.pow (-4) 31(= Int.min_value)Int.min_valueInt64.pow (-2L) 63LInt64.min_valueInt64.pow (-8L) 21LInt64.min_valueInt64.pow Int64.min_value 0L1LOne note on the issue: on 63-bit
int,(-2) ** 62 = 2 ** 62, which does overflow, so raising there is correct. Theintcase that reachesmin_valueis(-4) ** 31.Changes
generate_pow_overflow_bounds.ml: compute negative bounds against-(max_value + 1)for odd exponents (and for 0 and 1), and againstmax_valuefor even ones. Emit negative tables for every type, using the same per-architecture structure as the positiveinttable. Negativeintentries are parenthesized insideStdlib.Int64.to_int (...).pow_overflow_bounds.ml/.mli: regenerated. Positive tables are unchanged. Inint64_negative_overflow_bounds, only exponents 0, 1, 3, 7, 9, 21 and 63 change.int_math.ml:int_powandint63_pow_on_int64compare signed bases against the positive and negative bounds, asint64_powalready does. This also removes the now-unusedabs_local.Testing
I don't have an OxCaml toolchain, so I haven't built Base itself. What I did check:
pow_overflow_bounds.ml. Every new negative boundbat exponentesatisfiesmin_value <= b ** e, andb - 1overflows.Iarray/Portability_hacks) together with the new checks and an OCaml port ofBase_int_math_int_pow_stub. Comparedint,int64and int63-on-int64 results against Zarith for about 210k (base, exponent) pairs: bases from -300 to 300, ±2^k ± 1, every table bound ± 1, andmin_value/max_value; exponents 0 to 70. There were no mismatches.