diff options
| author | Yukihiro "Matz" Matsumoto <[email protected]> | 2018-08-01 21:55:11 +0900 |
|---|---|---|
| committer | Yukihiro "Matz" Matsumoto <[email protected]> | 2018-08-25 09:16:01 +0900 |
| commit | f3564a405ee766797be191cedd90aa3ab8b5e5c5 (patch) | |
| tree | c6a91e7787a32d0cab7fb6bb7f4f6a742f3fde0d /src | |
| parent | 322eb2328a516f7d92e35850d730b022bd948c23 (diff) | |
| download | mruby-f3564a405ee766797be191cedd90aa3ab8b5e5c5.tar.gz mruby-f3564a405ee766797be191cedd90aa3ab8b5e5c5.zip | |
Small refactoring of `flodivmod()`.
Diffstat (limited to 'src')
| -rw-r--r-- | src/numeric.c | 41 |
1 files changed, 26 insertions, 15 deletions
diff --git a/src/numeric.c b/src/numeric.c index 4e5fc394e..c3e7d77a3 100644 --- a/src/numeric.c +++ b/src/numeric.c @@ -220,29 +220,40 @@ flo_mul(mrb_state *mrb, mrb_value x) } static void -flodivmod(mrb_state *mrb, mrb_float x, mrb_float y, mrb_float *divp, mrb_float *modp) +flodivmod(mrb_state *mrb, double x, double y, mrb_float *divp, mrb_float *modp) { - mrb_float div; - mrb_float mod; + double div, mod; + if (isnan(y)) { + /* y is NaN so all results are NaN */ + div = mod = y; + goto exit; + } if (y == 0.0) { - if (x > 0.0) div = INFINITY; - else if (x < 0.0) div = -INFINITY; - else div = NAN; /* x == 0.0 */ + if (x == 0) div = NAN; + else if (x > 0.0) div = INFINITY; + else div = -INFINITY; /* x < 0.0 */ mod = NAN; + goto exit; + } + if ((x == 0.0) || (isinf(y) && !isinf(x))) { + mod = x; } else { mod = fmod(x, y); - if (isinf(x) && isfinite(y)) - div = x; - else - div = (x - mod) / y; - if (y*mod < 0) { - mod += y; - div -= 1.0; - } } - + if (isinf(x) && !isinf(y)) { + div = x; + } + else { + div = (x - mod) / y; + if (modp && divp) div = round(div); + } + if (y*mod < 0) { + mod += y; + div -= 1.0; + } + exit: if (modp) *modp = mod; if (divp) *divp = div; } |
