diff options
| author | Laytan <laytanlaats@hotmail.com> | 2024-08-20 19:00:49 +0200 |
|---|---|---|
| committer | Laytan <laytanlaats@hotmail.com> | 2024-08-20 19:01:09 +0200 |
| commit | 8f2d3dc955f1135c64a03236e57ddd97186a18aa (patch) | |
| tree | 8e5d89cacd14d9136e1106ffd03bb99415fd151a /base/runtime | |
| parent | daa0779c019738ffe775e80e8c1a4f76cd4b1e0f (diff) | |
fix i128 division?
Diffstat (limited to 'base/runtime')
| -rw-r--r-- | base/runtime/internal.odin | 26 |
1 files changed, 22 insertions, 4 deletions
diff --git a/base/runtime/internal.odin b/base/runtime/internal.odin index 1f85fb569..ff60cf547 100644 --- a/base/runtime/internal.odin +++ b/base/runtime/internal.odin @@ -1014,14 +1014,32 @@ modti3 :: proc "c" (a, b: i128) -> i128 { @(link_name="__divmodti4", linkage=RUNTIME_LINKAGE, require=RUNTIME_REQUIRE) divmodti4 :: proc "c" (a, b: i128, rem: ^i128) -> i128 { - u := udivmod128(u128(a), u128(b), (^u128)(rem)) - return i128(u) + s_a := a >> (128 - 1) // -1 if negative or 0 + s_b := b >> (128 - 1) + an := (a ~ s_a) - s_a // absolute + bn := (b ~ s_b) - s_b + + s_b ~= s_a // quotient sign + u_s_b := u128(s_b) + u_s_a := u128(s_a) + + r: u128 = --- + u := i128((udivmodti4(u128(an), u128(bn), &r) ~ u_s_b) - u_s_b) // negate if negative + rem^ = i128((r ~ u_s_a) - u_s_a) + return u } @(link_name="__divti3", linkage=RUNTIME_LINKAGE, require=RUNTIME_REQUIRE) divti3 :: proc "c" (a, b: i128) -> i128 { - u := udivmodti4(u128(a), u128(b), nil) - return i128(u) + s_a := a >> (128 - 1) // -1 if negative or 0 + s_b := b >> (128 - 1) + an := (a ~ s_a) - s_a // absolute + bn := (b ~ s_b) - s_b + + s_a ~= s_b // quotient sign + u_s_a := u128(s_a) + + return i128((udivmodti4(u128(an), u128(bn), nil) ~ u_s_a) - u_s_a) // negate if negative } |