diff options
author | matz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 1998-03-17 10:06:57 +0000 |
---|---|---|
committer | matz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 1998-03-17 10:06:57 +0000 |
commit | 4c3d81d323f2876d5528fc9601cff55c88c6f566 (patch) | |
tree | 92eb620a2238c53401118b9ca5c920dbb1ca7d91 /bignum.c | |
parent | a94679135080615136be4d83a66b3f964b8d66a4 (diff) |
modulo, frexp, ldexp
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/v1_1r@126 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'bignum.c')
-rw-r--r-- | bignum.c | 44 |
1 files changed, 35 insertions, 9 deletions
@@ -662,12 +662,13 @@ big_mul(x, y) } static void -bigdivmod(x, y, div, mod) +bigdivmod(x, y, div, mod, modulo) VALUE x, y; VALUE *div, *mod; + int modulo; { UINT nx = RBIGNUM(x)->len, ny = RBIGNUM(y)->len, i, j; - VALUE z; + VALUE yy, z; USHORT *xds, *yds, *zds, *tds; unsigned long t2; long num; @@ -703,8 +704,8 @@ bigdivmod(x, y, div, mod) if (nx==ny) zds[nx+1] = 0; while (!yds[ny-1]) ny--; if ((dd = BIGRAD/(int)(yds[ny-1]+1)) != 1) { - y = big_clone(y); - tds = BDIGITS(y); + yy = big_clone(y); + tds = BDIGITS(yy); j = 0; num = 0; while (j<ny) { @@ -776,7 +777,16 @@ bigdivmod(x, y, div, mod) } } RBIGNUM(*mod)->len = ny; - RBIGNUM(*mod)->sign = RBIGNUM(y)->sign; + RBIGNUM(*mod)->sign = RBIGNUM(x)->sign; + if (modulo && RBIGNUM(x)->sign != RBIGNUM(y)->sign) { + int len = ny; + zds = BDIGITS(*mod); + while (len-- && !zds[len]); + if (len > 0) { + *mod = bigadd(*mod, y, 1); + return; + } + } *mod = bignorm(*mod); } } @@ -801,14 +811,16 @@ big_div(x, y) default: return num_coerce_bin(x, y); } - bigdivmod(x, y, &z, 0); + bigdivmod(x, y, &z, 0, 0); return z; } + static VALUE -big_mod(x, y) +big_modulo(x, y, modulo) VALUE x, y; + int modulo; { VALUE z; @@ -827,12 +839,26 @@ big_mod(x, y) default: return num_coerce_bin(x, y); } - bigdivmod(x, y, 0, &z); + bigdivmod(x, y, 0, &z, modulo); return z; } static VALUE +big_mod(x, y) + VALUE x, y; +{ + return big_modulo(x, y, 1); +} + +static VALUE +big_remainder(x, y) + VALUE x, y; +{ + return big_modulo(x, y, 0); +} + +static VALUE big_divmod(x, y) VALUE x, y; { @@ -853,7 +879,7 @@ big_divmod(x, y) default: return num_coerce_bin(x, y); } - bigdivmod(x, y, &div, &mod); + bigdivmod(x, y, &div, &mod, 1); return assoc_new(div, mod);; } |