ref: e1e17a5cc5a65c21dec6a77ea4147a58610497f2
parent: 43a9edcd25ed37e9f043caa8498261af39cab081
author: S. Gilles <[email protected]>
date: Sun Jul 22 17:40:54 EDT 2018
Handle -0.0 correctly in tan() and cot().
--- a/lib/math/tan-impl.myr
+++ b/lib/math/tan-impl.myr
@@ -358,12 +358,25 @@
}
const tanorcot = {x : flt64, want_tan : bool
- var e : int64
- (_, e, _) = std.flt64explode(x)
+ var n : bool, e : int64, s : uint64
+ (n, e, s) = std.flt64explode(x)
+
if e == 1024
-> (std.flt64nan(), 0.0)
;;
+ if e == -1023 && s == 0x0
+ /* Special handling for +/-0.0 */
+ match (n, want_tan)
+ | (false, false): -> (std.flt64frombits(0x7ff0000000000000), 0.0)
+ | (false, true ): -> (std.flt64frombits(0x0000000000000000), 0.0)
+ | (true , false): -> (std.flt64frombits(0xfff0000000000000), 0.0)
+ | (true , true ): -> (std.flt64frombits(0x8000000000000000), 0.0)
+ ;;
+ ;;
+
+
+
var N : int64
var x1 : flt64, x2 : flt64
@@ -410,7 +423,7 @@
var p1, p2
/*
- Since cot() can blow up close to 0, just fall back to polynomial approximation
+ Since cot() can blow up close to 0, just fall back to polynomial approximation
*/
if x1 < 0.060546875
var s = x1 * x1
--- a/lib/math/test/tan-impl.myr
+++ b/lib/math/test/tan-impl.myr
@@ -40,7 +40,9 @@
const tancot01 = {c
var inputs : (uint32, uint32, uint32)[:] = [
(0x00000000, 0x00000000, 0x7f800000),
+ (0x80000000, 0x80000000, 0xff800000),
(0x01000000, 0x01000000, 0x7e000000),
+ (0x3c000000, 0x3c0000ab, 0x42fffeab),
][:]
for (x, yt, yc) : inputs
@@ -65,6 +67,7 @@
const tancot02 = {c
var inputs : (uint64, uint64, uint64)[:] = [
(0x0000000000000000, 0x0000000000000000, 0x7ff0000000000000),
+ (0x8000000000000000, 0x8000000000000000, 0xfff0000000000000),
(0x5101000000000000, 0xbff4f77bbc53c8f9, 0xbfe86b6d64c43ec0),
(0x4b01000000000000, 0xbfe96f60bbc6c837, 0xbff421332f057cb5),
(0x41bb951f1572eba5, 0xbc8f54f5227a4e84, 0xc35057584c429b3a), /* [GB91]'s "Xhard" */
@@ -94,6 +97,7 @@
const tancot03 = {c
var inputs : (uint64, uint64, uint64, uint64, uint64)[:] = [
(0xf83b13a6a142b6d5, 0xbf5a86f73542c78a, 0xc0834d0a344cbe85, 0xbf5a86f73542c789, 0xc0834d0a344cbe85),
+ (0x3f80000000000000, 0x3f800015557777af, 0x405fffd55549f49b, 0x3f800015557777af, 0x405fffd55549f49a),
][:]
for (x, yt_perfect, yc_perfect, yt_acceptable, yc_acceptable) : inputs