summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorS. Gilles <sgilles@math.umd.edu>2018-02-27 22:54:19 -0500
committerOri Bernstein <ori@eigenstate.org>2018-02-27 21:22:29 -0800
commit5f908a4b24cde049374c0922bce3cc067ab216dc (patch)
tree58af1900cda4c53e941758796bd7af033cf9e71b
parent19248d9673c0da5c189bf81e7c89a339cf99e405 (diff)
downloadmc-5f908a4b24cde049374c0922bce3cc067ab216dc.tar.gz
Test some fltbits functions
Test the isnan() and the float <-> bits functions, and correct slight error in isnan(). Adjust mantissa offset in flt32assem, but that function appears unused.
-rw-r--r--lib/std/fltbits.myr6
-rw-r--r--lib/std/test/fltbits.myr83
2 files changed, 85 insertions, 4 deletions
diff --git a/lib/std/fltbits.myr b/lib/std/fltbits.myr
index f4ddd54..81c3ef1 100644
--- a/lib/std/fltbits.myr
+++ b/lib/std/fltbits.myr
@@ -82,8 +82,8 @@ const flt32assem = {sign, mant, exp
s = (sign : uint32)
e = (exp : uint32) & 0xff
- m = (mant : uint32) & ((1<<22) - 1)
- -> std.flt32frombits(s << 31 | e << 22 | m)
+ m = (mant : uint32) & ((1<<23) - 1)
+ -> std.flt32frombits(s << 31 | e << 23 | m)
}
@@ -92,7 +92,7 @@ generic isnan = {f
b = flt64bits((f : flt64))
-> (b >> 52) & 0x7fful == 0x7fful && \
- b & ~(0x7fful) != 0
+ b & ~(0xffful << 52) != 0
}
const flt64inf = {
diff --git a/lib/std/test/fltbits.myr b/lib/std/test/fltbits.myr
index 357d292..6e3b7c3 100644
--- a/lib/std/test/fltbits.myr
+++ b/lib/std/test/fltbits.myr
@@ -5,6 +5,10 @@ use testr
const main = {
testr.run([
[.name = "isnan", .fn = isnan01],
+ [.name = "bits-roundtrip-32", .fn = bitsround32],
+ [.name = "bits-roundtrip-64", .fn = bitsround64],
+ [.name = "flt32bits", .fn = flt32bits],
+ [.name = "flt64bits", .fn = flt64bits],
][:])
}
@@ -12,6 +16,83 @@ const isnan01 = {c
testr.check(c, std.isnan(std.flt64nan()), "std.flt64nan() should give a NaN")
testr.check(c, std.isnan(std.flt32nan()), "std.flt32nan() should give a NaN")
+ /*
+ a NaN should be {any sign bit}, then {8 or 11 exponent
+ bits, all 1}, then {any non-zero sequence of 23 or 52
+ bits}
+ */
testr.check(c, std.isnan(std.flt64frombits(0xfff0000500000000ul)), "0xfff0000500000000 should be a NaN")
- testr.check(c, !std.isnan(std.flt64frombits(0xfff0000000000000ul)), "Infinities should not be NaNs")
+ testr.check(c, std.isnan(std.flt64frombits(0x7ff0000500000000ul)), "0x7ff0000500000000 should be a NaN")
+ testr.check(c, std.isnan(std.flt32frombits(0xff800090)), "0xff800090 should be a NaN")
+ testr.check(c, std.isnan(std.flt32frombits(0x7f800090)), "0x7f800090 should be a NaN")
+
+ /* if the significand bits are all 0, it's an infinity instead */
+ testr.check(c, !std.isnan(std.flt64frombits(0x7ff0000000000000ul)), "Infinities[1] should not be NaNs")
+ testr.check(c, !std.isnan(std.flt64frombits(0xfff0000000000000ul)), "Infinities[2] should not be NaNs")
+ testr.check(c, !std.isnan(std.flt32frombits(0xff800000)), "Infinities[3] should not be NaNs")
+ testr.check(c, !std.isnan(std.flt32frombits(0x7f800000)), "Infinities[4] should not be NaNs")
+}
+
+const bitsround32 = {c
+ for f : [1.0, 0.00001, 123.45, 1111111111111111.2, -1.9, -0.0001][:]
+ var g = std.flt32frombits(std.flt32bits(f))
+ testr.check(c, f == g, "flt -> bits -> flt non-identity: {} != {}", f, g)
+ ;;
+
+ for u : [0x7af80000, 0x12ab9800, 0x00000000, 0x00000001, 0x80000000, 0xc8903aa5][:]
+ var v = std.flt32bits(std.flt32frombits(u))
+ testr.check(c, u == v, "bits -> flt -> bits non-identity: {} != {}", u, v)
+ ;;
+
+ var nan_f = std.flt32frombits(0xff800090)
+ var nan_g = std.flt32frombits(std.flt32bits(nan_f))
+ testr.check(c, nan_f == nan_g, "flt -> bits -> flt non-identity for nan")
+
+ var inf_f = std.flt32frombits(0x7f800000)
+ var inf_g = std.flt32frombits(std.flt32bits(inf_f))
+ testr.check(c, inf_f == inf_g, "flt -> bits -> flt non-identity for inf")
+}
+
+const bitsround64 = {c
+ for f : [1.0, 0.00001, 123.45, 1111111111111111.2, -1.9, -0.0001][:]
+ var g = std.flt64frombits(std.flt64bits(f))
+ testr.check(c, f == g, "flt -> bits -> flt non-identity: {} != {}", f, g)
+ ;;
+
+ for u : [0x7ff3330a00120809, 0x0000000000000000, 0x0000000000000001, 0xffffff0000000001][:]
+ var v = std.flt64bits(std.flt64frombits(u))
+ testr.check(c, u == v, "bits -> flt -> bits non-identity: {} != {}", u, v)
+ ;;
+
+ var nan_f = std.flt64frombits(0x7ff000000000a000ul)
+ var nan_g = std.flt64frombits(std.flt64bits(nan_f))
+ testr.check(c, nan_f == nan_g, "flt -> bits -> flt non-identity for nan")
+
+ var inf_f = std.flt64frombits(0xfff0000000000000ul)
+ var inf_g = std.flt64frombits(std.flt64bits(inf_f))
+ testr.check(c, inf_f == inf_g, "flt -> bits -> flt non-identity for inf")
+}
+
+const flt32bits = {c
+ for (f, u) : [
+ (2.0, 0x40000000),
+ (1.0, 0x3f800000),
+ (0.0000123, 0x374e5c19),
+ (-993.83, 0xc478751f),
+ ][:]
+ var uprime = std.flt32bits(f)
+ testr.check(c, u == uprime, "flt32bits wrong for {}: 0x{x} != 0x{x}", f, u, uprime)
+ ;;
+}
+
+const flt64bits = {c
+ for (f, u) : [
+ (2.0, 0x4000000000000000ul),
+ (1.0, 0x3ff0000000000000ul),
+ (0.0000123, 0x3ee9cb8320b15070ul),
+ (-993.83, 0xc08f0ea3d70a3d71ul),
+ ][:]
+ var uprime = std.flt64bits(f)
+ testr.check(c, u == uprime, "flt64bits wrong for {}: 0x{x} != 0x{x}", f, u, uprime)
+ ;;
}