mirror of
https://github.com/roc-lang/roc.git
synced 2025-08-03 03:42:17 +00:00
Merge pull request #5263 from yukiomoto/fix-dec-div
Fix dec division problem
This commit is contained in:
commit
f79ef07012
1 changed files with 42 additions and 7 deletions
|
@ -553,7 +553,7 @@ fn mul_and_decimalize(a: u128, b: u128) i128 {
|
|||
|
||||
// Multiply two 128-bit ints and divide the result by 10^DECIMAL_PLACES
|
||||
//
|
||||
// Adapted from https://github.com/nlordell/ethnum-rs
|
||||
// Adapted from https://github.com/nlordell/ethnum-rs/blob/c9ed57e131bffde7bcc8274f376e5becf62ef9ac/src/intrinsics/native/divmod.rs
|
||||
// Copyright (c) 2020 Nicholas Rodrigues Lordello
|
||||
// Licensed under the Apache License version 2.0
|
||||
//
|
||||
|
@ -682,16 +682,25 @@ fn div_u256_by_u128(numer: U256, denom: u128) U256 {
|
|||
lo_overflowed = @subWithOverflow(u128, lo, 1, &lo);
|
||||
hi = hi -% @intCast(u128, @bitCast(u1, lo_overflowed));
|
||||
|
||||
// TODO this U256 was originally created by:
|
||||
// NOTE: this U256 was originally created by:
|
||||
//
|
||||
// ((hi as i128) >> 127).as_u256()
|
||||
//
|
||||
// ...however, I can't figure out where that function is defined.
|
||||
// Maybe it's defined using a macro or something. Anyway, hopefully
|
||||
// this is what it would do in this scenario.
|
||||
// As an implementation of `as_u256`, we wrap a negative value around to the maximum value of U256.
|
||||
|
||||
var s_u128 = math.shr(u128, hi, 127);
|
||||
var s_hi: u128 = undefined;
|
||||
var s_lo: u128 = undefined;
|
||||
if (s_u128 == 1) {
|
||||
s_hi = math.maxInt(u128);
|
||||
s_lo = math.maxInt(u128);
|
||||
} else {
|
||||
s_hi = 0;
|
||||
s_lo = 0;
|
||||
}
|
||||
var s = .{
|
||||
.hi = 0,
|
||||
.lo = math.shr(u128, hi, 127),
|
||||
.hi = s_hi,
|
||||
.lo = s_lo,
|
||||
};
|
||||
|
||||
carry = s.lo & 1;
|
||||
|
@ -1055,6 +1064,32 @@ test "div: 10 / 3" {
|
|||
try expectEqual(res, numer.div(denom));
|
||||
}
|
||||
|
||||
test "div: 341 / 341" {
|
||||
var number1: RocDec = RocDec.fromU64(341);
|
||||
var number2: RocDec = RocDec.fromU64(341);
|
||||
try expectEqual(RocDec.fromU64(1), number1.div(number2));
|
||||
}
|
||||
|
||||
test "div: 342 / 343" {
|
||||
var number1: RocDec = RocDec.fromU64(342);
|
||||
var number2: RocDec = RocDec.fromU64(343);
|
||||
var roc_str = RocStr.init("0.997084548104956268", 20);
|
||||
try expectEqual(RocDec.fromStr(roc_str), number1.div(number2));
|
||||
}
|
||||
|
||||
test "div: 680 / 340" {
|
||||
var number1: RocDec = RocDec.fromU64(680);
|
||||
var number2: RocDec = RocDec.fromU64(340);
|
||||
try expectEqual(RocDec.fromU64(2), number1.div(number2));
|
||||
}
|
||||
|
||||
test "div: 500 / 1000" {
|
||||
var number1: RocDec = RocDec.fromU64(500);
|
||||
var number2: RocDec = RocDec.fromU64(1000);
|
||||
var roc_str = RocStr.init("0.5", 3);
|
||||
try expectEqual(RocDec.fromStr(roc_str), number1.div(number2));
|
||||
}
|
||||
|
||||
// exports
|
||||
|
||||
pub fn fromStr(arg: RocStr) callconv(.C) num_.NumParseResult(i128) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue