diff options
author | Lukas Larsson <[email protected]> | 2011-11-01 10:10:31 +0100 |
---|---|---|
committer | Lukas Larsson <[email protected]> | 2011-11-01 10:10:31 +0100 |
commit | d5ebc4c1409284e0a343a64edf7d75308a1b3dd2 (patch) | |
tree | a863c845667a7a7dee0e4504c6b10aa1dfb5ed84 /erts/emulator/beam/big.c | |
parent | 668e7f7d2f8bf01f281065c19dd37dda4a499751 (diff) | |
parent | ec153fa6d7ba58a741e18f36b12736ec55243d35 (diff) | |
download | otp-d5ebc4c1409284e0a343a64edf7d75308a1b3dd2.tar.gz otp-d5ebc4c1409284e0a343a64edf7d75308a1b3dd2.tar.bz2 otp-d5ebc4c1409284e0a343a64edf7d75308a1b3dd2.zip |
Merge branch 'lukas/erts/large_float_cmp/OTP-9497'
* lukas/erts/large_float_cmp/OTP-9497:
Update documentation after changes in integer and float comparison
Do small optimisation on platforms with 32 bit Eterm
Add tests for equality checking
Optimize comparison of huge floats and smaller bignums
Add tests for comparing large floats and small bignums
Cleanup double_to_bignum conversion code
Update size of tmp cmp bignum buffer
Expand tests for float and number comparison
Update heauristic to work on halfword
Add heauristics bignum vs float checks
Optimise bugnum and small comparison
Add float vs integer comparison tests
Update integer and floating point number comparisons
Diffstat (limited to 'erts/emulator/beam/big.c')
-rw-r--r-- | erts/emulator/beam/big.c | 56 |
1 files changed, 56 insertions, 0 deletions
diff --git a/erts/emulator/beam/big.c b/erts/emulator/beam/big.c index d18de9ae5d..b90ea6b478 100644 --- a/erts/emulator/beam/big.c +++ b/erts/emulator/beam/big.c @@ -1584,6 +1584,62 @@ big_to_double(Wterm x, double* resp) return 0; } +/* + * Logic has been copied from erl_bif_guard.c and slightly + * modified to use a static instead of dynamic heap + */ +Eterm +double_to_big(double x, Eterm *heap) +{ + int is_negative; + int ds; + ErtsDigit* xp; + Eterm res; + int i; + size_t sz; + Eterm* hp; + double dbase; + + if (x >= 0) { + is_negative = 0; + } else { + is_negative = 1; + x = -x; + } + + /* Unscale & (calculate exponent) */ + ds = 0; + dbase = ((double) (D_MASK) + 1); + while (x >= 1.0) { + x /= dbase; /* "shift" right */ + ds++; + } + sz = BIG_NEED_SIZE(ds); /* number of words including arity */ + + hp = heap; + res = make_big(hp); + xp = (ErtsDigit*) (hp + 1); + + for (i = ds - 1; i >= 0; i--) { + ErtsDigit d; + + x *= dbase; /* "shift" left */ + d = x; /* trunc */ + xp[i] = d; /* store digit */ + x -= d; /* remove integer part */ + } + while ((ds & (BIG_DIGITS_PER_WORD - 1)) != 0) { + xp[ds++] = 0; + } + + if (is_negative) { + *hp = make_neg_bignum_header(sz-1); + } else { + *hp = make_pos_bignum_header(sz-1); + } + return res; +} + /* ** Estimate the number of decimal digits (include sign) |