ref: 1d7654102819c1db26c418cfdc9fb3032294157e
parent: debd13efe12eaca072229e9859aaa6df8708a09f
author: S. Gilles <sgilles@math.umd.edu>
date: Sat Mar 24 19:17:01 EDT 2018
Fix fma32 off-by-ones.
--- a/lib/math/fma-impl.myr
+++ b/lib/math/fma-impl.myr
@@ -107,10 +107,9 @@
base is 2, subtraction or addition are equally
useful.)
*/
- if (larger ^ shr(smaller, larger_e - smaller_e)) & 0x1 != 0
- mask >>= 1
+ if (larger ^ shr(smaller, larger_e - smaller_e)) & 0x1 == 0
+ prevent_rounding = smaller & mask != 0
;;
- prevent_rounding = smaller & mask != 0
else
/*
The prospective rounding agrees with the signage.
@@ -206,6 +205,10 @@
ts = (ts1 : uint32)
if need_round_away(0, s, shift)
ts++
+ if ts & (1 << 23) != 0
+ /* false alarm, it's normal again */
+ te++
+ ;;
;;
-> std.flt32assem(n, te, ts)
}
--- a/lib/math/fpmath.myr
+++ b/lib/math/fpmath.myr
@@ -3,15 +3,15 @@
pkg math =
trait fpmath @f =
- /* fpmath-fma-impl */
+ /* fma-impl */
fma : (x : @f, y : @f, z : @f -> @f)
- /* fpmath-trunc-impl */
+ /* trunc-impl */
trunc : (f : @f -> @f)
ceil : (f : @f -> @f)
floor : (f : @f -> @f)
- /* fpmath-sum-impl */
+ /* sum-impl */
kahan_sum : (a : @f[:] -> @f)
priest_sum : (a : @f[:] -> @f)
;;
--- a/lib/math/test/fma-impl.myr
+++ b/lib/math/test/fma-impl.myr
@@ -44,10 +44,13 @@
(0xa19e9a6f, 0xb49af3e3, 0xa2468b59, 0xa2468b57),
(0xd119e996, 0x8e5ad0e3, 0x247e0028, 0x247e83b7),
(0x381adbc6, 0x00ee4f61, 0x005f2aeb, 0x005f2d2c),
+ (0x7008233c, 0x2a9613fb, 0x46affd02, 0x5b1f9e8a),
+ (0xe85018a1, 0x2cbd53ed, 0x3fcffab8, 0xd599e668),
/* These ones are especially tricky */
(0x65dbf098, 0xd5beb8b4, 0x7c23db61, 0x73027654),
(0xa4932927, 0xc565bc34, 0x316887af, 0x31688bcf),
+ (0xb080a420, 0x09e2e5ca, 0x807ff1bf, 0x80800000),
][:]
for (x, y, z, r) : inputs