aboutsummaryrefslogtreecommitdiffstats
path: root/erts/emulator/beam/big.c
diff options
context:
space:
mode:
authorLukas Larsson <[email protected]>2011-11-01 10:10:31 +0100
committerLukas Larsson <[email protected]>2011-11-01 10:10:31 +0100
commitd5ebc4c1409284e0a343a64edf7d75308a1b3dd2 (patch)
treea863c845667a7a7dee0e4504c6b10aa1dfb5ed84 /erts/emulator/beam/big.c
parent668e7f7d2f8bf01f281065c19dd37dda4a499751 (diff)
parentec153fa6d7ba58a741e18f36b12736ec55243d35 (diff)
downloadotp-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.c56
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)