shithub: mc

Download patch

ref: e5833209e4cb397f5d17be79d81454b48002882a
parent: eff0ab25c1d542934e1a5d9df45da403777dd3c6
author: S. Gilles <sgilles@math.umd.edu>
date: Fri Jun 7 19:58:10 EDT 2019

Move hi/lo multiplication and addition routines to util.

--- a/lib/math/log-overkill.myr
+++ b/lib/math/log-overkill.myr
@@ -388,47 +388,3 @@
 
 	-> (lx_hi, lx_lo)
 }
-
-const hl_mult = {a_h : flt64, a_l : flt64, b_h : flt64, b_l : flt64
-	/*
-	       [     a_h    ][     a_l    ] * [     b_h    ][     b_l    ]
-	         =
-	   (A) [          a_h*b_h         ]
-	   (B)   +           [          a_h*b_l         ]
-	   (C)   +           [          a_l*b_h         ]
-	   (D)   +                         [          a_l*b_l         ]
-
-	   We therefore want to keep all of A, and the top halves of the two
-	   smaller products B and C.
-
-	   To be pedantic, *_l could be much smaller than pictured above; *_h and
-	   *_l need not butt up right against each other. But that won't cause
-	   any problems; there's no way we'll ignore important information.
-	 */
-	var Ah, Al
-	(Ah, Al) = two_by_two64(a_h, b_h)
-	var Bh = a_h * b_l
-	var Ch = a_l * b_h
-	var resh, resl, t1, t2
-	(resh, resl) = slow2sum(Bh, Ch)
-	(resl, t1) = fast2sum(Al, resl)
-	(resh, t2) = slow2sum(resh, resl)
-	(resh, resl) = slow2sum(Ah, resh)
-	-> (resh, resl + (t1 + t2))
-}
-
-const hl_add = {a_h : flt64, a_l : flt64, b_h : flt64, b_l : flt64
-	/*
-	  Not terribly clever, we just chain a couple of 2sums together. We are
-	  free to impose the requirement that |a_h| > |b_h|, because we'll only
-	  be using this for a = 1/5, 1/3, and the log(Fi)s from the C tables.
-	  However, we can't guarantee that a_l > b_l. For example, compare C1[10]
-	  to C2[18].
-	 */
-
-	var resh, resl, t1, t2
-	(t1, t2) = slow2sum(a_l, b_l)
-	(resl, t1) = slow2sum(b_h, t1)
-	(resh, resl) = fast2sum(a_h, resl)
-	-> (resh, resl + (t1 + t2))
-}
--- a/lib/math/util.myr
+++ b/lib/math/util.myr
@@ -19,6 +19,12 @@
 	const two_by_two64 : (x : flt64, y : flt64 -> (flt64, flt64))
 	const two_by_two32 : (x : flt32, y : flt32 -> (flt32, flt32))
 
+	/* Multiply (a_hi + a_lo) * (b_hi + b_lo) to (z_hi + z_lo) */
+	const hl_mult : (a_h : flt64, a_l : flt64, b_h : flt64, b_l : flt64 -> (flt64, flt64))
+
+	/* Add (a_hi + a_lo) * (b_hi + b_lo) to (z_hi + z_lo). Must have |a| > |b|. */
+	const hl_add : (a_h : flt64, a_l : flt64, b_h : flt64, b_l : flt64 -> (flt64, flt64))
+
 	/* Compare by magnitude */
 	const mag_cmp32 : (f : flt32, g : flt32 -> std.order)
 	const mag_cmp64 : (f : flt64, g : flt64 -> std.order)
@@ -249,6 +255,50 @@
 	var c  : flt32 = (cL : flt32)
 
 	-> (s, c)
+}
+
+const hl_mult = {a_h : flt64, a_l : flt64, b_h : flt64, b_l : flt64
+	/*
+	       [     a_h    ][     a_l    ] * [     b_h    ][     b_l    ]
+	         =
+	   (A) [          a_h*b_h         ]
+	   (B)   +           [          a_h*b_l         ]
+	   (C)   +           [          a_l*b_h         ]
+	   (D)   +                         [          a_l*b_l         ]
+
+	   We therefore want to keep all of A, and the top halves of the two
+	   smaller products B and C.
+
+	   To be pedantic, *_l could be much smaller than pictured above; *_h and
+	   *_l need not butt up right against each other. But that won't cause
+	   any problems; there's no way we'll ignore important information.
+	 */
+	var Ah, Al
+	(Ah, Al) = two_by_two64(a_h, b_h)
+	var Bh = a_h * b_l
+	var Ch = a_l * b_h
+	var resh, resl, t1, t2
+	(resh, resl) = slow2sum(Bh, Ch)
+	(resl, t1) = fast2sum(Al, resl)
+	(resh, t2) = slow2sum(resh, resl)
+	(resh, resl) = slow2sum(Ah, resh)
+	-> (resh, resl + (t1 + t2))
+}
+
+const hl_add = {a_h : flt64, a_l : flt64, b_h : flt64, b_l : flt64
+	/*
+	  Not terribly clever, we just chain a couple of 2sums together. We are
+	  free to impose the requirement that |a_h| > |b_h|, because we'll only
+	  be using this for a = 1/5, 1/3, and the log(Fi)s from the C tables.
+	  However, we can't guarantee that a_l > b_l. For example, compare C1[10]
+	  to C2[18].
+	 */
+
+	var resh, resl, t1, t2
+	(t1, t2) = slow2sum(a_l, b_l)
+	(resl, t1) = slow2sum(b_h, t1)
+	(resh, resl) = fast2sum(a_h, resl)
+	-> (resh, resl + (t1 + t2))
 }
 
 const mag_cmp32 = {f : flt32, g : flt32