Skip to content

Commit 56aab55

Browse files
committed
Fix #5931
Fix #5931 and add test case for it.
1 parent 784f320 commit 56aab55

File tree

3 files changed

+31
-19
lines changed

3 files changed

+31
-19
lines changed

core/math/big/internal.odin

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -746,19 +746,15 @@ internal_int_divmod :: proc(quotient, remainder, numerator, denominator: ^Int, a
746746

747747
if (denominator.used > 2 * MUL_KARATSUBA_CUTOFF) && (denominator.used <= (numerator.used / 3) * 2) {
748748
assert(denominator.used >= 160 && numerator.used >= 240, "MUL_KARATSUBA_CUTOFF global not properly set.")
749-
err = _private_int_div_recursive(quotient, remainder, numerator, denominator)
749+
return _private_int_div_recursive(quotient, remainder, numerator, denominator)
750750
} else {
751-
when true {
752-
err = #force_inline _private_int_div_school(quotient, remainder, numerator, denominator)
753-
} else {
754-
/*
755-
NOTE(Jeroen): We no longer need or use `_private_int_div_small`.
756-
We'll keep it around for a bit until we're reasonably certain div_school is bug free.
757-
*/
758-
err = _private_int_div_small(quotient, remainder, numerator, denominator)
759-
}
751+
return #force_inline _private_int_div_school(quotient, remainder, numerator, denominator)
752+
/*
753+
NOTE(Jeroen): We no longer need or use `_private_int_div_small`.
754+
We'll keep it around for a bit until we're reasonably certain div_school is bug free.
755+
*/
756+
// err = _private_int_div_small(quotient, remainder, numerator, denominator)
760757
}
761-
return
762758
}
763759

764760
/*

core/math/big/private.odin

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1050,7 +1050,6 @@ _private_int_div_school :: proc(quotient, remainder, numerator, denominator: ^In
10501050
Normalize both x and y, ensure that y >= b/2, [b == 2**MP_DIGIT_BIT]
10511051
*/
10521052
norm := internal_count_bits(y) % _DIGIT_BITS
1053-
10541053
if norm < _DIGIT_BITS - 1 {
10551054
norm = (_DIGIT_BITS - 1) - norm
10561055
internal_shl(x, x, norm) or_return
@@ -1070,33 +1069,29 @@ _private_int_div_school :: proc(quotient, remainder, numerator, denominator: ^In
10701069
y = y*b**{n-t}
10711070
*/
10721071

1072+
10731073
_private_int_shl_leg(y, n - t) or_return
10741074

1075-
gte := internal_gte(x, y)
1076-
for gte {
1075+
for internal_gte(x, y) {
10771076
q.digit[n - t] += 1
10781077
internal_sub(x, x, y) or_return
1079-
gte = internal_gte(x, y)
10801078
}
10811079

10821080
/*
10831081
Reset y by shifting it back down.
10841082
*/
10851083
_private_int_shr_leg(y, n - t)
1086-
10871084
/*
10881085
Step 3. for i from n down to (t + 1).
10891086
*/
10901087
#no_bounds_check for i := n; i >= (t + 1); i -= 1 {
10911088
if i > x.used { continue }
1092-
10931089
/*
10941090
step 3.1 if xi == yt then set q{i-t-1} to b-1, otherwise set q{i-t-1} to (xi*b + x{i-1})/yt
10951091
*/
10961092
if x.digit[i] == y.digit[t] {
1097-
q.digit[(i - t) - 1] = 1 << (_DIGIT_BITS - 1)
1093+
q.digit[(i - t) - 1] = 1 << _DIGIT_BITS - 1
10981094
} else {
1099-
11001095
tmp := _WORD(x.digit[i]) << _DIGIT_BITS
11011096
tmp |= _WORD(x.digit[i - 1])
11021097
tmp /= _WORD(y.digit[t])

tests/core/math/big/test_core_math_big.odin

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,27 @@ test_big_math_vectors :: proc(t: ^testing.T) {
224224
}
225225
}
226226

227+
@(test)
228+
bug_5931 :: proc(t: ^testing.T) {
229+
numerator, divisor, quotient, remainder: big.Int
230+
defer big.destroy(&numerator, &divisor, &quotient, &remainder)
231+
232+
big.string_to_int(&numerator, "3351951982485649274893506249551461531869841455148098344430890360930192345844485855956241793418914802713278852793799976230545127411560969441984014513833901")
233+
big.string_to_int(&divisor, "115792089237316195423570985008687907853269984665640564039457584007908834671663")
234+
235+
big.int_divmod(&quotient, &remainder, &numerator, &divisor)
236+
quo_str, _ := big.int_itoa_string(&quotient)
237+
defer delete(quo_str)
238+
assert(quo_str == "28948022309329048855892746252171976963317496166410141009864396001977208667923")
239+
240+
rem_str, _ := big.int_itoa_string(&remainder)
241+
defer delete(rem_str)
242+
assert(rem_str == "28948022309329048855892746252171976963317496166410141009864396001977208667952")
243+
}
244+
245+
246+
// Test helpers
247+
227248
expect_a :: proc(t: ^testing.T, format: string, a, expected, res: ^big.Int, err: big.Error, loc := #caller_location) {
228249
if err != .Okay { return }
229250

0 commit comments

Comments
 (0)