Skip to content

Commit

Permalink
Fix rounding mode handling: round() and roundf() always round away fr…
Browse files Browse the repository at this point in the history
…om zero, independent of current active rounding mode, and rint() family should respect the active rounding mode (we only implement one - FE_TONEAREST i.e. round-to-even, or banker's rounding)
  • Loading branch information
juj committed Nov 3, 2017
1 parent 9df31d0 commit 7036e58
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 14 deletions.
42 changes: 29 additions & 13 deletions src/library.js
Original file line number Diff line number Diff line change
Expand Up @@ -1581,8 +1581,6 @@ LibraryManager.library = {
llvm_ceil_f64: 'Math_ceil',
llvm_floor_f32: 'Math_floor',
llvm_floor_f64: 'Math_floor',
llvm_round_f32: 'Math_round',
llvm_round_f64: 'Math_round',

llvm_exp2_f32: function(x) {
return Math.pow(2, x);
Expand Down Expand Up @@ -1615,31 +1613,49 @@ LibraryManager.library = {
},

roundf__asm: true,
roundf__sig: 'dd',
roundf: function(f) {
roundf__sig: 'ff',
roundf: function(d) {
d = +d;
return d >= +0 ? +Math_floor(d + +0.5) : +Math_ceil(d - +0.5);
},

llvm_round_f64__asm: true,
llvm_round_f64__sig: 'dd',
llvm_round_f64: function(d) {
d = +d;
return d >= +0 ? +Math_floor(d + +0.5) : +Math_ceil(d - +0.5);
},

llvm_round_f32__asm: true,
llvm_round_f32__sig: 'ff',
llvm_round_f32: function(f) {
f = +f;
return f >= +0 ? +Math_floor(f + +0.5) : +Math_ceil(f - +0.5); // TODO: use fround?
},

rintf__asm: true,
rintf__sig: 'ff',
rintf__deps: ['round'],
rintf: function(f) {
f = +f;
return (f - +Math_floor(f) != .5) ? +_round(f) : +_round(f / +2) * +2;
},

// TODO: fround?
llvm_rint_f32__asm: true,
llvm_rint_f32__sig: 'dd',
llvm_rint_f32__sig: 'ff',
llvm_rint_f32__deps: ['roundf'],
llvm_rint_f32: function(f) {
f = +f;
if (+Math_abs(+Math_floor(f + +1) - f) < +Math_abs(+Math_ceil(f - +1) - f)) {
return +Math_floor(f + +1);
}
return +Math_ceil(f - +1);
return (f - +Math_floor(f) != .5) ? +_roundf(f) : +_roundf(f / +2) * +2;
},

llvm_rint_f64__asm: true,
llvm_rint_f64__sig: 'dd',
llvm_rint_f64__deps: ['round'],
llvm_rint_f64: function(f) {
f = +f;
if (+Math_abs(+Math_floor(f + +1) - f) < +Math_abs(+Math_ceil(f - +1) - f)) {
return +Math_floor(f + +1);
}
return +Math_ceil(f - +1);
return (f - +Math_floor(f) != .5) ? +_round(f) : +_round(f / +2) * +2;
},

_reallyNegative: function(x) {
Expand Down
2 changes: 1 addition & 1 deletion tools/system_libs.py
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ def create_libc(libname):
blacklist = set(
['ipc', 'passwd', 'thread', 'signal', 'sched', 'ipc', 'time', 'linux', 'aio', 'exit', 'legacy', 'mq', 'process', 'search', 'setjmp', 'env', 'ldso', 'conf'] + # musl modules
['memcpy.c', 'memset.c', 'memmove.c', 'getaddrinfo.c', 'getnameinfo.c', 'inet_addr.c', 'res_query.c', 'gai_strerror.c', 'proto.c', 'gethostbyaddr.c', 'gethostbyaddr_r.c', 'gethostbyname.c', 'gethostbyname2_r.c', 'gethostbyname_r.c', 'gethostbyname2.c', 'usleep.c', 'alarm.c', 'syscall.c', '_exit.c'] + # individual files
['abs.c', 'cos.c', 'cosf.c', 'cosl.c', 'sin.c', 'sinf.c', 'sinl.c', 'tan.c', 'tanf.c', 'tanl.c', 'acos.c', 'acosf.c', 'acosl.c', 'asin.c', 'asinf.c', 'asinl.c', 'atan.c', 'atanf.c', 'atanl.c', 'atan2.c', 'atan2f.c', 'atan2l.c', 'exp.c', 'expf.c', 'expl.c', 'log.c', 'logf.c', 'logl.c', 'sqrt.c', 'sqrtf.c', 'sqrtl.c', 'fabs.c', 'fabsf.c', 'fabsl.c', 'ceil.c', 'ceilf.c', 'ceill.c', 'floor.c', 'floorf.c', 'floorl.c', 'pow.c', 'powf.c', 'powl.c', 'round.c', 'roundf.c'] # individual math files
['abs.c', 'cos.c', 'cosf.c', 'cosl.c', 'sin.c', 'sinf.c', 'sinl.c', 'tan.c', 'tanf.c', 'tanl.c', 'acos.c', 'acosf.c', 'acosl.c', 'asin.c', 'asinf.c', 'asinl.c', 'atan.c', 'atanf.c', 'atanl.c', 'atan2.c', 'atan2f.c', 'atan2l.c', 'exp.c', 'expf.c', 'expl.c', 'log.c', 'logf.c', 'logl.c', 'sqrt.c', 'sqrtf.c', 'sqrtl.c', 'fabs.c', 'fabsf.c', 'fabsl.c', 'ceil.c', 'ceilf.c', 'ceill.c', 'floor.c', 'floorf.c', 'floorl.c', 'pow.c', 'powf.c', 'powl.c', 'round.c', 'roundf.c', 'rintf.c'] # individual math files
)
# TODO: consider using more math code from musl, doing so makes box2d faster
for dirpath, dirnames, filenames in os.walk(musl_srcdir):
Expand Down

0 comments on commit 7036e58

Please sign in to comment.