Skip to content

Commit eb6a8e6

Browse files
bnoordhuisandrewrk
authored andcommittedJun 20, 2018
fix f128 remainder division bug
The modulo operation computed rem(b+rem(a,b), b) which produces -1 for a=1 and b=2. Switch to a - b * trunc(a/b) which produces the expected result, 1. closes #1137
·
0.15.20.3.0
1 parent 4eca75c commit eb6a8e6

File tree

2 files changed

+23
-3
lines changed

2 files changed

+23
-3
lines changed
 

‎src/ir.cpp‎

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7710,6 +7710,14 @@ static void float_rem(ConstExprValue *out_val, ConstExprValue *op1, ConstExprVal
77107710
}
77117711
}
77127712

7713+
// c = a - b * trunc(a / b)
7714+
static void zig_f128M_mod(const float128_t* a, const float128_t* b, float128_t* c) {
7715+
f128M_div(a, b, c);
7716+
f128M_roundToInt(c, softfloat_round_min, true, c);
7717+
f128M_mul(b, c, c);
7718+
f128M_sub(a, c, c);
7719+
}
7720+
77137721
static void float_mod(ConstExprValue *out_val, ConstExprValue *op1, ConstExprValue *op2) {
77147722
assert(op1->type == op2->type);
77157723
out_val->type = op1->type;
@@ -7724,9 +7732,7 @@ static void float_mod(ConstExprValue *out_val, ConstExprValue *op1, ConstExprVal
77247732
out_val->data.x_f64 = fmod(fmod(op1->data.x_f64, op2->data.x_f64) + op2->data.x_f64, op2->data.x_f64);
77257733
return;
77267734
case 128:
7727-
f128M_rem(&op1->data.x_f128, &op2->data.x_f128, &out_val->data.x_f128);
7728-
f128M_add(&out_val->data.x_f128, &op2->data.x_f128, &out_val->data.x_f128);
7729-
f128M_rem(&out_val->data.x_f128, &op2->data.x_f128, &out_val->data.x_f128);
7735+
zig_f128M_mod(&op1->data.x_f128, &op2->data.x_f128, &out_val->data.x_f128);
77307736
return;
77317737
default:
77327738
zig_unreachable();

‎test/cases/math.zig‎

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -434,6 +434,20 @@ test "comptime float rem int" {
434434
}
435435
}
436436

437+
test "remainder division" {
438+
comptime remdiv(f32);
439+
comptime remdiv(f64);
440+
comptime remdiv(f128);
441+
remdiv(f32);
442+
remdiv(f64);
443+
remdiv(f128);
444+
}
445+
446+
fn remdiv(comptime T: type) void {
447+
assert(T(1) == T(1) % T(2));
448+
assert(T(1) == T(7) % T(3));
449+
}
450+
437451
test "@sqrt" {
438452
testSqrt(f64, 12.0);
439453
comptime testSqrt(f64, 12.0);

0 commit comments

Comments
 (0)
Please sign in to comment.