Skip to content

Commit

Permalink
Fix arithmetic overflow in umul192_lower128.
Browse files Browse the repository at this point in the history
Doesn't affect release builds, but extracting the mid 64 bits in
`umul192_lower128` leads to arithmetic overflow in `hi + (hi_lo >> 64)
as u64`, causing an undesirable panic.

Closes #84.
  • Loading branch information
Alexhuszagh committed May 14, 2022
1 parent effaae8 commit 13df1ef
Show file tree
Hide file tree
Showing 2 changed files with 9 additions and 1 deletion.
3 changes: 2 additions & 1 deletion lexical-write-float/src/algorithm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -874,7 +874,8 @@ pub const fn umul192_upper128(x: u64, hi: u64, lo: u64) -> (u64, u64) {
pub const fn umul192_lower128(x: u64, yhi: u64, ylo: u64) -> (u64, u64) {
let hi = x.wrapping_mul(yhi);
let hi_lo = x as u128 * ylo as u128;
(hi + (hi_lo >> 64) as u64, hi_lo as u64)
// NOTE: This can wrap exactly to 0, and this is desired.
(hi.wrapping_add((hi_lo >> 64) as u64), hi_lo as u64)
}

#[inline(always)]
Expand Down
7 changes: 7 additions & 0 deletions lexical-write-float/tests/algorithm_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,13 @@ fn floor_log10_pow2_minus_log10_4_over_3_test() {
}
}

#[test]
fn issue84_test() {
let (hi, lo) = algorithm::umul192_lower128(15966911296221875, 0xcccccccccccccccc, 0xcccccccccccccccd);
assert_eq!(hi, 0);
assert_eq!(lo, 3193382259244375);
}

#[test]
fn pow32_test() {
assert_eq!(algorithm::pow32(10, 1), 10);
Expand Down

0 comments on commit 13df1ef

Please sign in to comment.