ref: 6235cb639285f9ff5a7fc483a1950a8cd42f9aa9
parent: 88df32c77ff6806dee396803b8a9145f53c04ae3
author: Ori Bernstein <ori@eigenstate.org>
date: Sat Sep 19 20:29:46 EDT 2015
Fix floating point formatting.
--- a/lib/std/bigint.myr
+++ b/lib/std/bigint.myr
@@ -266,7 +266,9 @@
for var i = a.dig.len; i > 0; i--
da = a.dig[i - 1] castto(int64)
db = b.dig[i - 1] castto(int64)
- -> signedorder(sa * (da - db))
+ if da != db
+ -> signedorder(sa * (da - db))
+ ;;
;;
;;
-> `Equal
--- a/lib/std/fltfmt.myr
+++ b/lib/std/fltfmt.myr
@@ -19,11 +19,17 @@
const Dblbias = 1023
const Fltbias = 127
+const Dblminmant = 1 << 52 /* the minimum mantissa for a normal float. */
const flt64bfmt = {sb, val, mode, precision
var isneg, exp, mant
(isneg, mant, exp) = flt64explode(val)
+ /* adjust for denormals */
+ while mant < Dblminmant
+ mant <<= 1
+ exp--
+ ;;
dragon4(sb, isneg, mant, (exp - 52) castto(int64), Dblbias, mode, precision)
}
@@ -163,6 +169,7 @@
;;
while true
k--
+
bigmuli(r, 10)
u = bigdup(r);
bigdiv(u, s)
@@ -179,16 +186,20 @@
| _:
;;
bigfree(t)
-
+
+ /* v = 2*r */
v = bigdup(r)
bigshli(v, 1)
+
+ /* t = 2*s - mp */
t = bigdup(s)
bigshli(t, 1)
bigsub(t, mp)
+
match bigcmp(v, t)
- | `After: high = true
- | `Equal: high = roundup
- | `Before: high = false
+ | `Before: high = false;
+ | `Equal: high = roundup;
+ | `After: high = true;
;;
bigfree(v)
bigfree(t)
--- a/lib/std/test/bigint.myr
+++ b/lib/std/test/bigint.myr
@@ -37,6 +37,27 @@
n = std.bigbfmt(buf[:], a, 0)
std.assert(std.sleq(buf[:n], "517347321949036993306"), "simple smoke test failed")
+ /* some comparison tests */
+ a = try(std.bigparse("1234_5678_1234_6789_6666_7777_8888"))
+ b = try(std.bigparse("2234_5678_1234_6789_6666_7777_8888"))
+ match std.bigcmp(a, b)
+ | `std.Before: /* everything is as it should be */
+ | `std.Equal: std.fatal("lies: {} == {}\n", a, b)
+ | `std.After: std.fatal("lies: {} > {}\n", a, b)
+ ;;
+ std.bigfree(a)
+ std.bigfree(b)
+
+ a = try(std.bigparse("36028797018963964"))
+ b = try(std.bigparse("36028797018963958"))
+ match std.bigcmp(a, b)
+ | `std.Before: std.fatal("lies: {} < {}\n", a, b)
+ | `std.Equal: std.fatal("lies: {} == {}\n", a, b)
+ | `std.After: /* everything is as it should be */
+ ;;
+ std.bigfree(a)
+ std.bigfree(b)
+
/* make sure we format '0' correctly */
run(std.mk(`Val "0"), "0")
/* smoke test for division */