shithub: mc

Download patch

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