[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):