[PATCH 1/2] Adjust signs of fltbits functions
[Thread Prev] | [Thread Next]
- Subject: [PATCH 1/2] Adjust signs of fltbits functions
- From: "S. Gilles" <sgilles@xxxxxxxxxxxx>
- Reply-to: myrddin-dev@xxxxxxxxxxxxxx
- Date: Tue, 27 Feb 2018 22:54:18 -0500
- To: "myrddin-dev" <myrddin-dev@xxxxxxxxxxxxxx>
- Cc: "S. Gilles" <sgilles@xxxxxxxxxxxx>
The fltXYbits and fltXYfrombits functions now return/take unsigned
integers uniformly, allowing easier round-tripping. Unsigned was
chosen to emphasize that the value of the result is probably unrelated
to the floating-point value.
The fltXYexplode and fltXYassem functions now return the mantissa
(significand) unsigned, but the exponent signed. This reflects the
allowed ranges represented by the encoding.
---
lib/std/fltbits.myr | 40 +++++++++++++++++++++-------------------
lib/std/fltfmt.myr | 2 +-
lib/std/fltparse.myr | 4 ++--
lib/std/test/fltbits.myr | 14 +++++++++++++-
4 files changed, 37 insertions(+), 23 deletions(-)
diff --git a/lib/std/fltbits.myr b/lib/std/fltbits.myr
index 765ce04f..f4ddd54f 100644
--- a/lib/std/fltbits.myr
+++ b/lib/std/fltbits.myr
@@ -1,6 +1,6 @@
pkg std =
- const flt64bits : (flt : flt64 -> int64)
- const flt32bits : (flt : flt32 -> int32)
+ const flt64bits : (flt : flt64 -> uint64)
+ const flt32bits : (flt : flt32 -> uint32)
const flt64inf : (-> flt64)
const flt64nan : (-> flt64)
const flt32inf : (-> flt32)
@@ -9,28 +9,29 @@ pkg std =
generic isnan : (f : @a -> bool) ::floating @a
const flt64frombits : (bits : uint64 -> flt64)
const flt32frombits : (bits : uint32 -> flt32)
- const flt64explode : (flt : flt64 -> (bool, int64, int64))
- const flt32explode : (flt : flt32 -> (bool, int32, int32))
- const flt64assem : (sign : bool, mant : int64, exp : int64 -> flt64)
- const flt32assem : (sign : bool, mant : int32, exp : int32 -> flt32)
+ const flt64explode : (flt : flt64 -> (bool, uint64, int64))
+ const flt32explode : (flt : flt32 -> (bool, uint32, int32))
+ const flt64assem : (sign : bool, mant : uint64, exp : int64 -> flt64)
+ const flt32assem : (sign : bool, mant : uint32, exp : int32 -> flt32)
;;
-const flt64bits = {flt; -> (&flt : int64#)#}
-const flt32bits = {flt; -> (&flt : int32#)#}
+const flt64bits = {flt; -> (&flt : uint64#)#}
+const flt32bits = {flt; -> (&flt : uint32#)#}
const flt64frombits = {bits; -> (&bits : flt64#)#}
const flt32frombits = {bits; -> (&bits : flt32#)#}
const flt64explode = {flt
- var bits, isneg, mant, exp
+ var bits, isneg, mant, uexp, exp
bits = flt64bits(flt)
isneg = (bits >> 63) != 0 /* msb is sign bit */
- exp = (bits >> 52) & 0x7ff /* exp is in bits [52..63] */
- mant = bits & ((1l << 52) - 1) /* msb is in bits [..51] */
+ uexp = (bits >> 52) & 0x7ff /* exp is in bits [52..63] */
+ mant = bits & ((1ul << 52) - 1) /* mant is in bits [..51] */
/* add back the implicit bit if this is not a denormal */
- if exp != 0
- mant |= 1l << 52
+ if uexp != 0
+ mant |= 1ul << 52
+ exp = (uexp : int64)
else
exp = 1
;;
@@ -44,16 +45,17 @@ const flt64explode = {flt
}
const flt32explode = {flt
- var bits, isneg, mant, exp
+ var bits, isneg, mant, uexp, exp
bits = flt32bits(flt)
isneg = (bits >> 31) != 0 /* msb is sign bit */
- exp = (bits >> 23) & 0xff /* exp is in bits [23..30] */
- mant = bits & ((1 << 23) - 1) /* msb is in bits [0..22] */
+ uexp = (bits >> 23) & 0xff /* exp is in bits [23..30] */
+ mant = bits & ((1 << 23) - 1) /* mant is in bits [0..22] */
/* add back the implicit bit if this is not a denormal */
- if exp != 0
+ if uexp != 0
mant |= 1 << 23
+ exp = (uexp : int32)
else
exp = 1
;;
@@ -89,8 +91,8 @@ generic isnan = {f
var b
b = flt64bits((f : flt64))
- -> (b >> 52) & 0x7ffl == 0x7ffl && \
- b & ~(0x7ffl) != 0
+ -> (b >> 52) & 0x7fful == 0x7fful && \
+ b & ~(0x7fful) != 0
}
const flt64inf = {
diff --git a/lib/std/fltfmt.myr b/lib/std/fltfmt.myr
index 2a36daf0..b0c08c42 100644
--- a/lib/std/fltfmt.myr
+++ b/lib/std/fltfmt.myr
@@ -32,7 +32,7 @@ const flt32bfmt = {sb, val, mode, precision
var isneg, exp, mant
(isneg, mant, exp) = flt32explode(val)
- dragon4(sb, isneg, (mant : int64), (exp - 23 : int64), Fltbias, mode, precision)
+ dragon4(sb, isneg, (mant : uint64), (exp - 23 : int64), Fltbias, mode, precision)
}
/*
diff --git a/lib/std/fltparse.myr b/lib/std/fltparse.myr
index 9836d1f2..e88eba6d 100644
--- a/lib/std/fltparse.myr
+++ b/lib/std/fltparse.myr
@@ -125,7 +125,7 @@ type lim = struct
minsig : uint64
maxsig : uint64
loshift : uint64
- nextinc : int64
+ nextinc : uint64
minexp : int16
maxexp : int16
sigbits : int16
@@ -265,7 +265,7 @@ const nextfloat = {z, lim
var za
(sign, mant, exp) = std.flt64explode(z)
- if std.abs(mant - (1l << 52) - 1) < lim.nextinc
+ if std.abs((mant : int64) - (1l << 52) - 1) < (lim.nextinc : int64)
mant = 0
exp++
else
diff --git a/lib/std/test/fltbits.myr b/lib/std/test/fltbits.myr
index 4e641379..357d2923 100644
--- a/lib/std/test/fltbits.myr
+++ b/lib/std/test/fltbits.myr
@@ -1,5 +1,17 @@
use std
+use testr
+
const main = {
- std.assert(std.isnan(std.flt64nan()), "isnan(nan) false\n")
+ testr.run([
+ [.name = "isnan", .fn = isnan01],
+ ][:])
+}
+
+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")
+
+ 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")
}
--
2.16.2
| [PATCH 0/2] Signedness of bits from floats | "S. Gilles" <sgilles@xxxxxxxxxxxx> |
- Prev by Date: [PATCH 0/2] Signedness of bits from floats
- Next by Date: [PATCH 2/2] Test some fltbits functions
- Previous by thread: [PATCH 0/2] Signedness of bits from floats
- Next by thread: [PATCH 2/2] Test some fltbits functions
- Index(es):