Skip to content

Commit 77dc09b

Browse files
committed
Fix inaccurate round while being fast
This patch applies a clever rounding approach to fix subtle correctness bugs in the implementation of float rounding. It uses copysign to avoid branching, and with the hope of using llvm intrinsics where available. Work in progress, tests are missing. Fixes emscripten-core#7306
1 parent b9bfdbc commit 77dc09b

File tree

1 file changed

+8
-4
lines changed

1 file changed

+8
-4
lines changed

src/library.js

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1566,30 +1566,34 @@ LibraryManager.library = {
15661566

15671567
round__asm: true,
15681568
round__sig: 'dd',
1569+
round__deps: ['llvm_copysign_f64'],
15691570
round: function(d) {
15701571
d = +d;
1571-
return d >= +0 ? +Math_floor(d + +0.5) : +Math_ceil(d - +0.5);
1572+
return +_llvm_copysign_f64(+Math_floor((+Math_abs(d) + +0.2499999999999999) + +0.2500000000000001), d);
15721573
},
15731574

15741575
roundf__asm: true,
15751576
roundf__sig: 'ff',
1577+
roundf__deps: ['llvm_copysign_f64'],
15761578
roundf: function(d) {
15771579
d = +d;
1578-
return d >= +0 ? +Math_floor(d + +0.5) : +Math_ceil(d - +0.5);
1580+
return +_llvm_copysign_f64(+Math_floor((+Math_abs(d) + +0.2499999999999999) + +0.2500000000000001), d);
15791581
},
15801582

15811583
llvm_round_f64__asm: true,
15821584
llvm_round_f64__sig: 'dd',
1585+
llvm_round_f64__deps: ['llvm_copysign_f64'],
15831586
llvm_round_f64: function(d) {
15841587
d = +d;
1585-
return d >= +0 ? +Math_floor(d + +0.5) : +Math_ceil(d - +0.5);
1588+
return +_llvm_copysign_f64(+Math_floor((+Math_abs(d) + +0.2499999999999999) + +0.2500000000000001), d);
15861589
},
15871590

15881591
llvm_round_f32__asm: true,
15891592
llvm_round_f32__sig: 'ff',
1593+
llvm_round_f32__deps: ['llvm_copysign_f64'],
15901594
llvm_round_f32: function(f) {
15911595
f = +f;
1592-
return f >= +0 ? +Math_floor(f + +0.5) : +Math_ceil(f - +0.5); // TODO: use fround?
1596+
return +_llvm_copysign_f64(+Math_floor((+Math_abs(d) + +0.2499999999999999) + +0.2500000000000001), d);
15931597
},
15941598

15951599
rintf__asm: true,

0 commit comments

Comments
 (0)