shithub: mc

Download patch

ref: 56a659f634f2a591cf641eb875a4e7f457c40321
parent: 527b74f79517336b3ef11c963e86658527aa96cd
author: S. Gilles <sgilles@math.umd.edu>
date: Tue Jul 31 08:03:40 EDT 2018

First compiling atan.

--- a/lib/math/ancillary/generate-arctan-tuples-for-GB91.c
+++ b/lib/math/ancillary/generate-arctan-tuples-for-GB91.c
@@ -1,4 +1,5 @@
 /* cc -o generate-arctan-tuples-for-GB91 generate-arctan-tuples-for-GB91.c -lmpfr # -fno-strict-aliasing */
+/* cc -static -std=c99 -D_POSIX_C_SOURCE=999999999 -fno-strict-aliasing -O2 -o generate-arctan-tuples-for-GB91 generate-arctan-tuples-for-GB91.c -lmpfr -lgmp */
 #include <errno.h>
 #include <stdint.h>
 #include <stdio.h>
@@ -244,7 +245,7 @@
         /* Compute (xij)^(-1) */
         invert_poorly(xij, xijinv);
 
-        while (r < (1 << 26)) {
+        while (r < (1 << 28)) {
                 xi = xi_orig + r;
                 xi_d = UINT64_TO_FLT64(xi);
                 mpfr_set_d(xi_m, xi_d, MPFR_RNDN);
--- a/lib/math/ancillary/generate-minimax-by-Remez.gp
+++ b/lib/math/ancillary/generate-minimax-by-Remez.gp
@@ -127,6 +127,10 @@
         return(if(x == 0, 1, tan(x)/x));
 }
 
+{ atanxoverx(x) =
+        return(if(x == 0, 1, atan(x)/x));
+}
+
 { cotx(x) =
         return(1/tanoverx(x));
 }
@@ -162,6 +166,13 @@
 find_minimax(tanoverx, 10, 0, 15.5/256)
 print("\n");
 print("(You'll need to add a 0x0 at the beginning to make a degree 11...\n");
+print("\n");
+print("---\n");
+print("\n");
+print("Minmimaxing atan(x) / x, degree 12, on [0, 15.5/256]:");
+find_minimax(atanxoverx, 12, 0, 1/16)
+print("\n");
+print("(You'll need to add a 0x0 at the beginning to make a degree 13...\n");
 print("\n");
 print("---\n");
 print("Remember that there's that extra, ugly E term at the end of the vector that you want to lop off.\n");
--- /dev/null
+++ b/lib/math/atan-impl.myr
@@ -1,0 +1,422 @@
+use std
+
+use "fpmath"
+
+use "sin-impl"
+use "util"
+
+/*
+   As with other trig functions, we follow [GB91] here. This is a
+   relatively straight-forward "tabulate and approximate by local
+   polynomials" approach. The (relative) lack of sophistication can
+   be seen by the huge number of constants required. The only fancy
+   trick is that
+
+      atan(x) + atan(1/x) = pi/2
+
+   which allows quick reduction to the range [-1, 1].
+
+   The Highly Accurate Table approach of [GB91] then appears in the
+   constants for the polynomial approximations. This acts as a few
+   bits of insurance against subtractive cancellation of the first
+   few terms of the polynomial approximations.
+
+   See files generate-atan-tuples-for-GB91.c, and
+   generate-minimax-by-Remez.gp for where the constants come from.
+ */
+pkg math =
+	pkglocal const atan32 : (x : flt32 -> flt32)
+	pkglocal const atan64 : (x : flt64 -> flt64)
+
+	pkglocal const atan232 : (y : flt32, x : flt32 -> flt32)
+	pkglocal const atan264 : (y : flt64, x : flt64 -> flt64)
+;;
+
+/*
+   Coefficients for p(x), where arctan(x) is approximated in degree
+   13 by x*p(x^2).
+ */
+const atan_coeffs : uint64[7] = [
+	0x3ff0000000000000,
+	0xbfd5555555555555,
+	0x3fc9999999999128,
+	0xbfc2492493302077,
+	0x3fbc71bd4ec2b9ae,
+	0xbfb750eefa902315,
+	0x3fb226324f0122e0,
+]
+
+/*
+   Coefficients for degree 5 polynomial approximations of arctan(x)
+   on intervals of width 1/256, roughly filling the [0, 1] space.
+   Because of the slight shifting of the pivot xi variables by up
+   to 2^26 ulps, there are tiny gaps, of up to size 2*2^(-53 + 26)
+   = 2^-26, on which the minimax guarantees do not apply. This is
+   not expected to be a significant issue.
+
+   Note that the first few entries aren't actually used.
+ */
+const C : (uint64, uint64, uint64, uint64, uint64, uint64, uint64)[257] = [
+	(0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000),
+	(0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000),
+	(0x3f80000001f83362, 0xbf7fffd559ac119a, 0x3fefff8001ffd883, 0x3f7fff0009e129ba, 0xbfd55355689e3241, 0xbf7ffdcf9a784a0c, 0x3fc995f4bed14247),
+	(0x3f87ffffff37811c, 0xbf87ffb800bc4b32, 0x3feffee00a1fb7b6, 0x3f87fe5015f2c284, 0xbfd550d5b96bfd9c, 0xbf87fc076a4fd120, 0x3fc98fc8b892a7b2),
+	(0x3f8fffffffc1eade, 0xbf8fff555b7d615a, 0x3feffe001ffe07ed, 0x3f8ffc005fa9b585, 0xbfd54d5693a075a5, 0xbf8ff657f61b9dd7, 0x3fc9869ee5cadbbd),
+	(0x3f93fffffe0e9f70, 0xbf93ff595d2776fd, 0x3feffce04e18fad7, 0x3f93fc18907a7f60, 0xbfd548d85eda9a6c, 0xbf93f61bf2de1558, 0x3fc97abe5d2bf700),
+	(0x3f97ffffffec7ecd, 0xbf97fee01836ddc0, 0x3feffb80a1e94266, 0x3f97f9416c2a7c14, 0xbfd5435ba3ccdd9c, 0xbf97eefc49b67b90, 0x3fc96b9f97155700),
+	(0x3f9c000002043a2b, 0xbf9bfe36e12cee80, 0x3feff9e12be5b739, 0x3f9bf54b150fb215, 0xbfd53ce105d2bb59, 0xbf9be5104edd8ee0, 0x3fc9598af87d1c00),
+	(0x3fa00000022e99a5, 0xbf9ffd55c0059267, 0x3feff801ff7df250, 0x3f9ff006025a63b6, 0xbfd5356946bb4ad9, 0xbf9fd7e22b0f4cc0, 0x3fc94484728b9380),
+	(0x3fa200000058e037, 0xbfa1fe1a5c8788b8, 0x3feff5e3331c6ffa, 0x3fa1f4a166090962, 0xbfd52cf545c2c2d0, 0xbfa1e37e5b434560, 0x3fc92c909999c980),
+	(0x3fa3fffffe4fe9f8, 0xbfa3fd65efba5c58, 0x3feff384e01a9106, 0x3fa3f0692146d108, 0xbfd5238601c8043d, 0xbfa3d95263db398f, 0x3fc9116fa0344708),
+	(0x3fa5fffffd7d0899, 0xbfa5fc89a378731e, 0x3feff0e722c403ee, 0x3fa5eb42b2d510f3, 0xbfd5191c8f45f7ad, 0xbfa5cc83e91b1137, 0x3fc8f3b166e52899),
+	(0x3fa7fffffff47d57, 0xbfa7fb8184255df7, 0x3fefee0a1a5143a8, 0x3fa7e516b6ddd4cd, 0xbfd50dba2684300b, 0xbfa7bd2cb777bd9a, 0x3fc8d317587dd676),
+	(0x3fa9fffffc2c23a9, 0xbfa9fa4994982dbb, 0x3fefeaede8f76900, 0x3fa9ddcddc883e9e, 0xbfd501601a419c50, 0xbfa9ab141ce95d64, 0x3fc8afa883cd8ab3),
+	(0x3fabfffffd0f0cbd, 0xbfabf8ddee4b0fc3, 0x3fefe792b3b38c6e, 0x3fabd5510839a77b, 0xbfd4f40fd8f0a91b, 0xbfab9602138cdbe9, 0x3fc8896c8f290450),
+	(0x3fae000000ffdc11, 0xbfadf73aa09e1477, 0x3fefe3f8a27756be, 0x3fadcb8935b8415f, 0xbfd4e5cae94695f1, 0xbfad7d32cd68db68, 0x3fc860b09a86ff00),
+	(0x3fb0000002ad31a4, 0xbfaff55bbc820c23, 0x3fefe01fe0154058, 0x3fafc05f85dd78f3, 0xbfd4d692f8f482ea, 0xbfaf617ebeb00bd8, 0x3fc834f3a9931b00),
+	(0x3fb100000188824f, 0xbfb0f99ea8a41bcd, 0x3fefdc089a435d4f, 0x3fb0d9de9f1c8568, 0xbfd4c669ca505107, 0xbfb0a166428a466f, 0x3fc8063f36448e35),
+	(0x3fb20000009bc757, 0xbfb1f86dbfa33080, 0x3fefd7b3016f7596, 0x3fb1d2c5eedc6080, 0xbfd4b55130ac22d8, 0xbfb18fd8c2bb0ee4, 0x3fc7d526db38f039),
+	(0x3fb3000024c171ae, 0xbfb2f7195618302f, 0x3fefd31f48358ab4, 0x3fb2cadaa8a559c1, 0xbfd4a34b240cff5f, 0xbfb27c47c2ad49a6, 0x3fc7a1702e4d8d69),
+	(0x3fb4000000068d16, 0xbfb3f59f0e82d887, 0x3fefce4da6ab73c7, 0x3fb3c2114d1e9dc2, 0xbfd49059bce708bf, 0xbfb36699156cde19, 0x3fc76b264479966d),
+	(0x3fb4ffffffdaf503, 0xbfb4f3fd674dc761, 0x3fefc93e53a2ae2c, 0x3fb4b85f4a8c15c6, 0xbfd47c7f1d6673be, 0xbfb44eb3ca7ef180, 0x3fc7325487c15892),
+	(0x3fb60000005453f7, 0xbfb5f23250268d66, 0x3fefc3f18b52cb50, 0x3fb5adb99d22e5c3, 0xbfd467bd8b4de796, 0xbfb5347ee36faada, 0x3fc6f706fed2d6e1),
+	(0x3fb7000000057dfc, 0xbfb6f03bdcefbdc7, 0x3fefbe678c078564, 0x3fb6a2157e35172d, 0xbfd452176286cdb9, 0xbfb617e1fe0c1388, 0x3fc6b94a23d2539a),
+	(0x3fb7fffffe7c548b, 0xbfb7ee182482a642, 0x3fefb8a096b5e8ba, 0x3fb7956844e7782f, 0xbfd43b8f17095f3f, 0xbfb6f8c53a2a94dc, 0x3fc6792ae7109ee3),
+	(0x3fb9000000399ffa, 0xbfb8ebc544b20fc7, 0x3fefb29ceedb75bc, 0x3fb887a76b0a59ee, 0xbfd4242733f64aa6, 0xbfb7d7114183708e, 0x3fc636b6a9a36669),
+	(0x3fba000000503ea3, 0xbfb9e941541f49d9, 0x3fefac5cdacc38c0, 0x3fb978c880930264, 0xbfd40be25c5cc9fc, 0xbfb8b2af3f76ad1f, 0x3fc5f1fb3caa1a83),
+	(0x3fbafffffefd604e, 0xbfbae68a70c75b65, 0x3fefa5e0a3559ff9, 0x3fba68c13a88c726, 0xbfd3f2c349624f3b, 0xbfb98b88f1f263f7, 0x3fc5ab06d90ee046),
+	(0x3fbc0000027ada67, 0xbfbbe39ec0e260e9, 0x3fef9f2893aa9d84, 0x3fbb578774c87524, 0xbfd3d8ccc2282c36, 0xbfba6104a32547f8, 0x3fc5622c6b5cdc00),
+	(0x3fbcfffffe2aae0e, 0xbfbce07c5a6d6a81, 0x3fef9834fa03c879, 0x3fbc45111ba09bf8, 0xbfd3be01baf8bc7a, 0xbfbb3410872e3840, 0x3fc516f2437f8a00),
+	(0x3fbe000001dab907, 0xbfbddd2171f3051f, 0x3fef910626538a70, 0x3fbd3154591dc7f9, 0xbfd3a2652c4d0b90, 0xbfbc04a65d78b257, 0x3fc4c967e0fd9461),
+	(0x3fbeffffffa53a79, 0xbfbed98c21368e87, 0x3fef899c6bd1f677, 0x3fbe1c47601d7e8f, 0xbfd385fa159fbfca, 0xbfbcd19beca90b8c, 0x3fc47a256b36705a),
+	(0x3fc000000f142d5a, 0xbfbfd5bab85dc3d0, 0x3fef81f81e981366, 0x3fbf05e0b86e7006, 0xbfd368c39b4690e4, 0xbfbd9b66d4a9b7f8, 0x3fc428f6923eacde),
+	(0x3fc07ffffcdf1951, 0xbfc068d5810d5bd4, 0x3fef7a19994da3f1, 0x3fbfee169210a60e, 0xbfd34ac4fcd8967e, 0xbfbe61f4253945ff, 0x3fc3d5ebc0588a79),
+	(0x3fc1000002aa39f4, 0xbfc0e6adcf926f2e, 0x3fef7201326bccc1, 0x3fc06a70037899d2, 0xbfd32c01735432c2, 0xbfbf25323b0051d6, 0x3fc38115615f521e),
+	(0x3fc18000001fea3b, 0xbfc1646541255ca1, 0x3fef69af483d2f52, 0x3fc0dd19dadefc1f, 0xbfd30c7c5e62ba59, 0xbfbfe50f8f51460e, 0x3fc32a845cd3502a),
+	(0x3fc1fffffe8823bc, 0xbfc1e1faf993a4c8, 0x3fef612438bab95f, 0x3fc14f04587e458a, 0xbfd2ec3924d36b33, 0xbfc050bdc309e406, 0x3fc2d249bb3c927d),
+	(0x3fc27ffffc9337b0, 0xbfc25f6e13bf7bd7, 0x3fef586064c338f8, 0x3fc1c02b10b43292, 0xbfd2cb3b4055087c, 0xbfc0ad330fd21a61, 0x3fc27876c32ba8fe),
+	(0x3fc2fffffdc6bf7b, 0xbfc2dcbdb0cea731, 0x3fef4f642f0fe16c, 0x3fc23089b1286391, 0xbfd2a98638fb0d98, 0xbfc107e008ee7ac7, 0x3fc21d1ce9880c12),
+	(0x3fc3800000c2fb33, 0xbfc359e8eeaa28a7, 0x3fef462ffcd452fe, 0x3fc2a01bf88e9498, 0xbfd2871da71092b5, 0xbfc160bd5de46b03, 0x3fc1c04dd31f291d),
+	(0x3fc4000000d8f876, 0xbfc3d6eee99a2f23, 0x3fef3cc435a04a95, 0x3fc30eddb88397f1, 0xbfd26405321912f4, 0xbfc1b7c415010900, 0x3fc1621b4e780103),
+	(0x3fc48000000de728, 0xbfc453cec616b8c4, 0x3fef332142989e5d, 0x3fc37ccade8e0ca6, 0xbfd240408d609878, 0xbfc20ced92d9e381, 0x3fc1029747314f3d),
+	(0x3fc4ffffff0e7ab0, 0xbfc4d087a8ef1e63, 0x3fef29478efdfd42, 0x3fc3e9df6d60cba2, 0xbfd21bd3796a9ce3, 0xbfc26033953388f3, 0x3fc0a1d3c688050b),
+	(0x3fc57ffffc7377dc, 0xbfc54d18b69dbcdb, 0x3fef1f3788337a10, 0x3fc456177c933fea, 0xbfd1f6c1c37d2372, 0xbfc2b190331b73b1, 0x3fc03fe2eebeac95),
+	(0x3fc5ffffff069c34, 0xbfc5c9811d4c8683, 0x3fef14f19ce2618f, 0x3fc4c16f418df8ce, 0xbfd1d10f41eb9d16, 0xbfc300fde3b8367f, 0x3fbfb9addc08f782),
+	(0x3fc67ffffe3dace2, 0xbfc645bffdfed6b5, 0x3fef0a763ecf8d44, 0x3fc52be2fc09f17c, 0xbfd1aabfda46e407, 0xbfc34e776fde19e4, 0x3fbef18416e713f0),
+	(0x3fc6fffffe88eb88, 0xbfc6c1d4881ddaae, 0x3feeffc5e08c9b3d, 0x3fc5956f0e16385c, 0xbfd183d77857c309, 0xbfc399f803dfed36, 0x3fbe276d18332ee6),
+	(0x3fc77fffffbe804c, 0xbfc73dbde868750f, 0x3feef4e0f6d3f675, 0x3fc5fe0fed8db872, 0xbfd15c5a1291701e, 0xbfc3e37b24a92e8d, 0x3fbd5b8d76fa3afe),
+	(0x3fc7fffffc35d1d7, 0xbfc7b97b48251fed, 0x3feee9c7f89a7009, 0x3fc665c223be9680, 0xbfd1344ba9bdc601, 0xbfc42afcaf9262f8, 0x3fbc8e09cf02b355),
+	(0x3fc8800000a239dc, 0xbfc8350be43569e9, 0x3feede7b5cee6e27, 0x3fc6cc8260df5e45, 0xbfd10bb040c61a32, 0xbfc47078e771a1fe, 0x3fbbbf06908b1814),
+	(0x3fc90000027df7fa, 0xbfc8b06ee4ee22e7, 0x3feed2fb9e8bb11b, 0x3fc7324d5aa33c81, 0xbfd0e28be90da705, 0xbfc4b3ec5d56fe5c, 0x3fbaeea83980b70d),
+	(0x3fc9800002d31c2a, 0xbfc92ba37fbc8427, 0x3feec74938c8c904, 0x3fc7971fe886b4de, 0xbfd0b8e2b6d26476, 0xbfc4f55403930d95, 0x3fba1d131409b3ab),
+	(0x3fc9fffffcddfcfd, 0xbfc9a6a8e66a4ab7, 0x3feebb64a91453c7, 0x3fc7faf6f60a4367, 0xbfd08eb8c5fc4160, 0xbfc534ad23ed705c, 0x3fb94a6b493e7c18),
+	(0x3fca7fffff8b55ee, 0xbfca217e5fa0a315, 0x3feeaf4e6c86c253, 0x3fc85dcf96a2bb00, 0xbfd0641230fa59ed, 0xbfc571f56b9c5c8a, 0x3fb876d4adfc5ac3),
+	(0x3fcafffffd414cf5, 0xbfca9c23189f6ea5, 0x3feea30704596a99, 0x3fc8bfa6e0659b60, 0xbfd038f3200791fd, 0xbfc5ad2ad32c8d7a, 0x3fb7a273097623dd),
+	(0x3fcb7ffffe765c40, 0xbfcb169655d5327a, 0x3fee968ef1197db7, 0x3fc9207a13521ece, 0xbfd00d5fb7ad7b56, 0xbfc5e64bb64ff60a, 0x3fb6cd69b8f6e504),
+	(0x3fcc000000abc4ff, 0xbfcb90d753364d8b, 0x3fee89e6b5bbd593, 0x3fc980467fefa357, 0xbfcfc2b8463315e8, 0xbfc61d56c362a69c, 0x3fb5f7dbddfa3d81),
+	(0x3fcc7fffffda3e36, 0xbfcc0ae54d528b2b, 0x3fee7d0ed6b1420d, 0x3fc9df098ebe3358, 0xbfcf69d920a9cf8c, 0xbfc6524aff4b3332, 0x3fb521ec46597687),
+	(0x3fccfffffff895a3, 0xbfcc84bf8a6d20c0, 0x3fee7007d8e2c735, 0x3fca3cc0c754ee99, 0xbfcf102a3a0ed514, 0xbfc6849fe6a47028, 0x3fb44c40e5060800),
+	(0x3fcd800002e87b67, 0xbfccfe6550e0425b, 0x3fee62d242a27514, 0x3fca9969c88af14c, 0xbfceb5b42bd588bd, 0xbfc6b562a8259298, 0x3fb375f45f6e7800),
+	(0x3fce0000007c3fa1, 0xbfcd77d5df961e94, 0x3fee556e9c79c2d5, 0x3fcaf502433f724e, 0xbfce5a7f5c4a951a, 0xbfc6e49a1c28bf4d, 0x3fb29f2902804d52),
+	(0x3fce8000018c9844, 0xbfcdf11087c3e708, 0x3fee47dd6e4b27d1, 0x3fcb4f880dd31913, 0xbfcdfe93e4e6b22c, 0xbfc71130057e8a97, 0x3fb1c906570f0d02),
+	(0x3fcf0000011971a7, 0xbfce6a148fa0c60b, 0x3fee3a1f427d6bd1, 0x3fcba8f90d9b0ad8, 0xbfcda1fa4468eaa4, 0xbfc73baf35ad6fbc, 0x3fb0f329b1d71c3b),
+	(0x3fcf7fffffae07f0, 0xbfcee2e144d04e42, 0x3fee2c34a3e84e63, 0x3fcc015345086350, 0xbfcd44bad359c3db, 0xbfc76418a7b6f7b9, 0x3fb01db333c0e897),
+	(0x3fd0000003c8cfe7, 0xbfcf5b76004c2654, 0x3fee1e1e1d47929d, 0x3fcc5894d623e3cd, 0xbfcce6ddde8c38ac, 0xbfc78a6da87d134e, 0x3fae9184c911f786),
+	(0x3fd0400003e0f35b, 0xbfcfd3d2038a7c77, 0x3fee0fdc3d4407ce, 0x3fccaebbe9509c5a, 0xbfcc886bc113543a, 0xbfc7aeafca638093, 0x3face8ecd45e8a40),
+	(0x3fd08000032761cb, 0xbfd025fa53fb759e, 0x3fee016f90dfb3ea, 0x3fcd03c6cfa46b13, 0xbfcc296cbe2c693a, 0xbfc7d0e0f31c6cc9, 0x3fab41db5e90e29b),
+	(0x3fd0bffffd1bbae5, 0xbfd061ee9d889212, 0x3fedf2d8a7a1ddae, 0x3fcd57b3e8faad27, 0xbfcbc9e91c1a6c4e, 0xbfc7f1034f0598ee, 0x3fa99c8c39820b78),
+	(0x3fd0fffffda7b6b5, 0xbfd09dc595a7aa29, 0x3fede4180e167b90, 0x3fcdaa81c348841c, 0xbfcb69e8ff46f764, 0xbfc80f195bae93a5, 0x3fa7f9398b9c2669),
+	(0x3fd1400002df4b88, 0xbfd0d97ee7b72b9e, 0x3fedd52e54a32e74, 0x3fcdfc2ef2b6e464, 0xbfcb0974963c35fd, 0xbfc82b25d6d98068, 0x3fa6581c8d5f3f91),
+	(0x3fd18000007fef6f, 0xbfd1151a369b3ad0, 0x3fedc61c0ed3a8b3, 0x3fce4cba17180e39, 0xbfcaa89413bba312, 0xbfc8452bc0669ca5, 0x3fa4b96d672b82b0),
+	(0x3fd1bffffd750e56, 0xbfd1509738407215, 0x3fedb6e1cc5e56bc, 0x3fce9c22010b8ec2, 0xbfca474f8102a8b8, 0xbfc85d2e64dd2c0a, 0x3fa31d6268e4aace),
+	(0x3fd2000003ca0de4, 0xbfd18bf5a68ee3b3, 0x3feda7801cbd34e3, 0x3fceea659ca4de3f, 0xbfc9e5aed4b250a4, 0xbfc87331536725ba, 0x3fa184306c2c9ae3),
+	(0x3fd2400002036234, 0xbfd1c735230a790e, 0x3fed97f79692b2ec, 0x3fcf3783cc4f0a97, 0xbfc983ba20bb093a, 0xbfc887385275eb6c, 0x3f9fdc171f589263),
+	(0x3fd27fffffdfc6c4, 0xbfd2025567c6bf7b, 0x3fed8848caf35b89, 0x3fcf837ba93cd7cf, 0xbfc9217940ea8bf9, 0xbfc89947704663ae, 0x3f9cb64bbd3e6b8a),
+	(0x3fd2bffffed8628c, 0xbfd23d562a27d0d0, 0x3fed78744ce26842, 0x3fcfce4c5c6a3c83, 0xbfc8bef409ec6215, 0xbfc8a962f5b80e45, 0x3f999760297b6b81),
+	(0x3fd2fffffd9ac75c, 0xbfd278371e2461ca, 0x3fed687ab0799710, 0x3fd00bfa9178bb91, 0xbfc85c32431fb914, 0xbfc8b78f661ebb08, 0x3f967fb3033009f6),
+	(0x3fd33ffffe5a26b1, 0xbfd2b2f7fc188619, 0x3fed585c894c7f41, 0x3fd0303aaa9777f1, 0xbfc7f93b9bf3c072, 0xbfc8c3d17ee8c3ea, 0x3f936f9fb86fef86),
+	(0x3fd37ffffec1b143, 0xbfd2ed98795ef86b, 0x3fed481a6c610cdd, 0x3fd053e62ea7a861, 0xbfc79617b7755508, 0xbfc8ce2e3400f439, 0x3f90677ee0a18b9f),
+	(0x3fd3c000003531d6, 0xbfd328184fe61b16, 0x3fed37b4ee113238, 0x3fd076fce03b5660, 0xbfc732ce1eb44786, 0xbfc8d6aaaf852261, 0x3f8acf4b9ec59d46),
+	(0x3fd40000014b4f1a, 0xbfd362773835c112, 0x3fed272ca3a66d1e, 0x3fd0997e8b99570c, 0xbfc6cf664a09a01d, 0xbfc8dd4c4eb42bdc, 0x3f84e0cdba8b378e),
+	(0x3fd44000002a76ab, 0xbfd39cb4eb9caee5, 0x3fed168222b7fc82, 0x3fd0bb6b07fba0fc, 0xbfc66be79ca66f40, 0xbfc8e218a084b591, 0x3f7e0845137e79a8),
+	(0x3fd4800002f0ac40, 0xbfd3d6d12bd1b3a2, 0x3fed05b5fee9e15f, 0x3fd0dcc23bca443d, 0xbfc6085956bc3e59, 0xbfc8e5156401dd74, 0x3f7273c2f54049f0),
+	(0x3fd4c0000398c9cd, 0xbfd410cbb0adb15b, 0x3fecf4c8cf23b4a7, 0x3fd0fd8411e92f76, 0xbfc5a4c2b406c729, 0xbfc8e648851b1c4d, 0x3f5c14e6132786eb),
+	(0x3fd5000000d2b414, 0xbfd44aa43780e819, 0x3fece3bb2923ae3c, 0x3fd11db082866efc, 0xbfc5412ad0e80c83, 0xbfc8e5b81bf6df1b, 0xbf51090196534ac1),
+	(0x3fd5400000d97ce4, 0xbfd4845a8594a669, 0x3fecd28da0a43a9e, 0x3fd13d479421cbf8, 0xbfc4dd98a5510238, 0xbfc8e36a6a29d4e3, 0xbf6ec343ef3f561f),
+	(0x3fd580000083fbd8, 0xbfd4bdee58df2a56, 0x3fecc140cbd716cb, 0x3fd15c4952ee964a, 0xbfc47a131e7a5564, 0xbfc8df65d90205c1, 0xbf7a57ed6c513309),
+	(0x3fd5c0000018a579, 0xbfd4f75f739cb1b0, 0x3fecafd53ff0fa50, 0x3fd17ab5d724d2b5, 0xbfc416a10a536704, 0xbfc8d9b0f77c529d, 0xbf8292192630d9e3),
+	(0x3fd5fffffe824f64, 0xbfd530ad97fc72a4, 0x3fec9e4b92687e96, 0x3fd1988d427b2e5c, 0xbfc3b3491e63dea3, 0xbfc8d25278721643, 0xbf87e2c648beb0b9),
+	(0x3fd63fffff3a13ec, 0xbfd569d88d6ab865, 0x3fec8ca4574c4517, 0x3fd1b5cfc2bbdc5f, 0xbfc35011ee14077d, 0xbfc8c9512fe43c8d, 0xbf8d1d92ca8d1ca8),
+	(0x3fd67fffff856d0c, 0xbfd5a2e016f0f80e, 0x3fec7ae0242da62e, 0x3fd1d27d8ca121f4, 0xbfc2ed01fadabe3b, 0xbfc8beb4125cd6e8, 0xbf91210c8ebe0b06),
+	(0x3fd6bffffe40da9f, 0xbfd5dbc3fa317aac, 0x3fec68ff8df60300, 0x3fd1ee96df565754, 0xbfc28a1fa7a73942, 0xbfc8b282322cefbb, 0xbf93a7fd0b2cabf4),
+	(0x3fd7000000850018, 0xbfd61484037f999c, 0x3fec5703278a5d34, 0x3fd20a1c0634f09a, 0xbfc22771314a492b, 0xbfc8a4c2bc3a467a, 0xbf96236e9d5027af),
+	(0x3fd74000032958c9, 0xbfd64d1ff900be97, 0x3fec44eb85d056c0, 0x3fd2250d52489ac7, 0xbfc1c4fcc46a8260, 0xbfc8957cf8f5c2e9, 0xbf989337c85e3c31),
+	(0x3fd7800001f42af4, 0xbfd68597a1186566, 0x3fec32b93da9d11a, 0x3fd23f6b1d709665, 0xbfc162c871f645a7, 0xbfc884b849764b83, 0xbf9af73214886454),
+	(0x3fd7c000020a1e4e, 0xbfd6bdeacb96c300, 0x3fec206ce0efcd02, 0x3fd25935ce6835b1, 0xbfc100da1ecc4e75, 0xbfc8727c22994bf1, 0xbf9d4f3a6910e69e),
+	(0x3fd7ffffef4b942f, 0xbfd6f619333fae00, 0x3fec0e0708525d88, 0x3fd2726dcab05fb8, 0xbfc09f37b85d7a7c, 0xbfc85ed0151cb6ca, 0xbf9f9b2fc00147e3),
+	(0x3fd84000000e1b33, 0xbfd72e22d546f87e, 0x3febfb88369c3125, 0x3fd28b139d7910a3, 0xbfc03de69c5c8f9e, 0xbfc849bbac9f2806, 0xbfa0ed7b56485e08),
+	(0x3fd88000025752bc, 0xbfd76607548c2d8b, 0x3febe8f10c2b5b27, 0x3fd2a327b1acf5d8, 0xbfbfb9d951a88eda, 0xbfc83346a668b00a, 0xbfa207397a81490f),
+	(0x3fd8c000030eff1b, 0xbfd79dc68c3a3aab, 0x3febd64216bfa88e, 0x3fd2baaa9313a44f, 0xbfbef89e7a4b8711, 0xbfc81b78bad06d46, 0xbfa31ac6be01f8d3),
+	(0x3fd9000001646b31, 0xbfd7d5604c98efba, 0x3febc37be783ad55, 0x3fd2d19cd038f707, 0xbfbe38275d0e35cf, 0xbfc80259b3ae8770, 0xbfa42818bdbf14e0),
+	(0x3fd93fffff640ee2, 0xbfd80cd4698dc1aa, 0x3febb09f0e37b37e, 0x3fd2e7ff0093da3c, 0xbfbd787e5d4923f4, 0xbfc7e7f16509a908, 0xbfa52f26866c2b8d),
+	(0x3fd97ffffdf78491, 0xbfd84422b71e6925, 0x3feb9dac1a54d801, 0x3fd2fdd1c2de7d30, 0xbfbcb9ada303e230, 0xbfc7cc47acdded50, 0xbfa62fe87d13430b),
+	(0x3fd9c00001035746, 0xbfd87b4b0cfdf415, 0x3feb8aa399cd687a, 0x3fd31315be4d8968, 0xbfbbfbbf0e6d9a58, 0xbfc7af646fa7c2bc, 0xbfa72a586923b8a6),
+	(0x3fda000000ffe340, 0xbfd8b24d3a25bea9, 0x3feb77861d504643, 0x3fd327cb9da69e4a, 0xbfbb3ebc624b5dfa, 0xbfc7914f9d605de4, 0xbfa81e71361d0a89),
+	(0x3fda400000100095, 0xbfd8e92917038092, 0x3feb645431fd7c4a, 0x3fd33bf4161c483a, 0xbfba82af05253ec0, 0xbfc7721126702f2c, 0xbfa90c2f3fa9f863),
+	(0x3fda7fffffe222b8, 0xbfd91fde7cb74808, 0x3feb510e645d7829, 0x3fd34f8fe3a4d491, 0xbfb9c7a01f5fd899, 0xbfc751b0fe6efdd3, 0xbfa9f39021b08a68),
+	(0x3fdabffffed95691, 0xbfd9566d42a871d9, 0x3feb3db541373664, 0x3fd3629fc80afeac, 0xbfb90d98369c90d3, 0xbfc72f44fbe48540, 0xbfaad3a70aefe000),
+	(0x3fdb0000004583fc, 0xbfd98cd545886e51, 0x3feb2a49530ec627, 0x3fd375248cf7a4e4, 0xbfb854a0c7dada4b, 0xbfc70cb749bdaee0, 0xbfabae4bec818000),
+	(0x3fdb3ffffc2050fd, 0xbfd9c316597e02fc, 0x3feb16cb270de8bf, 0x3fd3871eff703673, 0xbfb79cc1ecb3e3f8, 0xbfc6e91fcc119ab0, 0xbfac829399932000),
+	(0x3fdb800003ac36ec, 0xbfd9f93069302d4b, 0x3feb033b41d7016a, 0x3fd3988ff9a15401, 0xbfb6e60411f5449e, 0xbfc6c57ea4699da3, 0xbfad516a451d0115),
+	(0x3fdbc00003fd5a1f, 0xbfda2f2341ba0bb7, 0x3feaef9a323ef369, 0x3fd3a97851fa0ac4, 0xbfb6306e7ee85ebe, 0xbfc69fed5d8e28b3, 0xbfae18ff332609af),
+	(0x3fdc0000039b3621, 0xbfda64eec6d30865, 0x3feadbe87e780073, 0x3fd3b9d8ebacdb82, 0xbfb57c08cdfb1b0a, 0xbfc6786dcb5c4d60, 0xbfaed958fd6d6000),
+	(0x3fdc400000a49b57, 0xbfda9a92d6285c97, 0x3feac826ae62f6c8, 0x3fd3c9b2ad31c963, 0xbfb4c8db56e0aecb, 0xbfc650fe5384d100, 0xbfaf944e806c6000),
+	(0x3fdc800001b0d7d2, 0xbfdad00f558b3c25, 0x3feab455465812ed, 0x3fd3d90684bfac31, 0xbfb416ecc8a08e19, 0xbfc628ac8bd8a750, 0xbfb0247eb73f7000),
+	(0x3fdcbfffff851ce5, 0xbfdb05642048528d, 0x3feaa074ce0698a1, 0x3fd3e7d5626ee3ae, 0xbfb366442a9359be, 0xbfc5ff804857c080, 0xbfb07bb6a4d84000),
+	(0x3fdcfffffe193401, 0xbfdb3a911c127cfd, 0x3fea8c85c8b1f3e1, 0x3fd3f6203e274e24, 0xbfb2b6e8269a6794, 0xbfc5d5814b5a6c10, 0xbfb0cfd354252000),
+	(0x3fdd400000235500, 0xbfdb6f962e90b921, 0x3fea7888b9051e04, 0x3fd403e8145c9461, 0xbfb208df2c5981f4, 0xbfc5aab74c19a030, 0xbfb120d984141000),
+	(0x3fdd80000286b038, 0xbfdba473399b82ae, 0x3fea647e227e11d3, 0x3fd4112de4ff3e7d, 0xbfb15c2f7dc2395e, 0xbfc57f29f8cba630, 0xbfb16ece5dded000),
+	(0x3fddc00001cef7fd, 0xbfdbd9281fcf3646, 0x3fea506687b5fab0, 0x3fd41df2b49c19d6, 0xbfb0b0df2042c910, 0xbfc552e0f214fba0, 0xbfb1b9b778d7e000),
+	(0x3fde0000004fc0e4, 0xbfdc0db4c9902cd8, 0x3fea3c42686ef7da, 0x3fd42a378d455f59, 0xbfb006f4457a3232, 0xbfc526eff3475f6d, 0xbfb2020c549fc7a9),
+	(0x3fde3fffff53e727, 0xbfdc42191f647305, 0x3fea281243b119b3, 0x3fd435fd7d3b143b, 0xbfaebce6fa454208, 0xbfc4f948161b503f, 0xbfb246f01632fcd7),
+	(0x3fde7ffffe4a0194, 0xbfdc7655094883b8, 0x3fea13d6980a5b5d, 0x3fd4414596489a02, 0xbfad6ec41b47fbf8, 0xbfc4c9eae58de1a0, 0xbfb2886a8dcd0000),
+	(0x3fdebfffff2d0b48, 0xbfdcaa687247ff28, 0x3fe9ff8fe22665c0, 0x3fd44c10ee631c8a, 0xbfac238be3c9f536, 0xbfc49afdfb9c85b0, 0xbfb2c764d01a0000),
+	(0x3fdefffffe2211e5, 0xbfdcde5341a8f7d7, 0x3fe9eb3e9f72a6e7, 0x3fd456609e708e83, 0xbfaadb471890deec, 0xbfc46b7a80ae40e0, 0xbfb303753a5c2000),
+	(0x3fdf400001e3314b, 0xbfdd1215683e1df1, 0x3fe9d6e348e546c7, 0x3fd46035c47f98ab, 0xbfa995fec6e063a5, 0xbfc43b67a5f30860, 0xbfb33ca3a9377000),
+	(0x3fdf800003a8d041, 0xbfdd45aeccdea6bf, 0x3fe9c27e5aa08505, 0x3fd469917fdb4a8f, 0xbfa853bbce31875a, 0xbfc40acc925a23f0, 0xbfb372f83dba2000),
+	(0x3fdfc000001f74ac, 0xbfdd791f5a2b6535, 0x3fe9ae104e8e2ac4, 0x3fd47274f3aafe74, 0xbfa714868a1a99ad, 0xbfc3d9b055497f10, 0xbfb3a67b69c57000),
+	(0x3fe0000003558fd9, 0xbfddac670ab76e44, 0x3fe999999777521d, 0x3fd47ae148877e35, 0xbfa5d867886713de, 0xbfc3a935919c77de, 0xbfb3d7a4b03bed7b),
+	(0x3fe020000337d712, 0xbfdddf85c0246f0a, 0x3fe9851ab14b1526, 0x3fd482d7a5dddc15, 0xbfa49f638c34686a, 0xbfc376100d9d1a30, 0xbfb40530d8726000),
+	(0x3fe0400000b62087, 0xbfde127b6c28d8fc, 0x3fe9709410c8e4b3, 0x3fd48a5937e72e68, 0xbfa36985896d6846, 0xbfc344b94377092e, 0xbfb430e35d9d8543),
+	(0x3fe06000020fc2e6, 0xbfde454809b1710d, 0x3fe95c062621c687, 0x3fd491672f00db4b, 0xbfa236d0d50efa28, 0xbfc311def4833020, 0xbfb4597aa3dcba29),
+	(0x3fe07ffffd1dd2ee, 0xbfde77eb7a8913af, 0x3fe947716adf56d1, 0x3fd49802ba11dc1c, 0xbfa1074bf3e6c5f4, 0xbfc2dd82145369e0, 0xbfb47f0161fcf000),
+	(0x3fe0a0000020ae23, 0xbfdeaa65c802a0b0, 0x3fe932d647a7f8b0, 0x3fd49e2d0f2d17c5, 0xbf9fb5fc526b9153, 0xbfc2a9edd8a10d00, 0xbfb4a25c9eca4000),
+	(0x3fe0bffffe62365e, 0xbfdedcb6d1b5ebed, 0x3fe91e35354713b3, 0x3fd4a3e76149657c, 0xbf9d63d88329f12e, 0xbfc276074acdc500, 0xbfb4c328bc780000),
+	(0x3fe0dfffff058c1a, 0xbfdf0ede976ba91e, 0x3fe9098e9e8a0791, 0x3fd4a932e90f89aa, 0xbf9b1835db6a2a2c, 0xbfc241d4acd80770, 0xbfb4e170117a3000),
+	(0x3fe1000000022af6, 0xbfdf40dd0b5775b6, 0x3fe8f4e2f2ee66e0, 0x3fd4ae10df38f0de, 0xbf98d31d9fe7cbba, 0xbfc20d5c35659f70, 0xbfb4fd3d151e8000),
+	(0x3fe11fffff8ab5a0, 0xbfdf72b220ee8980, 0x3fe8e032a092e141, 0x3fd4b2827e460418, 0xbf9694984ad2cdcb, 0xbfc1d8a4004008f0, 0xbfb5169a66a9f000),
+	(0x3fe14000015e176d, 0xbfdfa45dd5211a0b, 0x3fe8cb7e10c43f1d, 0x3fd4b68902f758ed, 0xbf945cad318f03e8, 0xbfc1a3b205241980, 0xbfb52d92cd84c000),
+	(0x3fe1600002c01245, 0xbfdfd5e01b9f65b5, 0x3fe8b6c5afc33871, 0x3fd4ba25aa85f813, 0xbf922b635f92cdb3, 0xbfc16e8c2b465870, 0xbfb542312c6ec000),
+	(0x3fe180000005b0df, 0xbfe0039c73c60584, 0x3fe8a209e92e4ca4, 0x3fd4bd59b35af61d, 0xbf9000c35a24191f, 0xbfc13a6a8ec6fa74, 0xbfb554eb109f6098),
+	(0x3fe19ffffcfd1f74, 0xbfe01c341c32ce05, 0x3fe88d4b228d3bc7, 0x3fd4c0265dfd8ea5, 0xbf8bb99bf9151606, 0xbfc104f00f064a5c, 0xbfb564f624f07b1f),
+	(0x3fe1bffffcc45037, 0xbfe034b706ac12f3, 0x3fe87889c0984b64, 0x3fd4c28ceb80b949, 0xbf877f0f7a3534d6, 0xbfc0ce1caea5dc80, 0xbfb5725eaa28f000),
+	(0x3fe1e000015d0939, 0xbfe04d25324d4a16, 0x3fe863c6277e23ec, 0x3fd4c48e9d66b268, 0xbf8351f1b06feba3, 0xbfc0986002b15e50, 0xbfb57e03f43a2000),
+	(0x3fe20000034260ab, 0xbfe0657e97550542, 0x3fe84f00c05a567c, 0x3fd4c62cb59d4924, 0xbf7e648be9263288, 0xbfc0628b48095ca0, 0xbfb5878723eec000),
+	(0x3fe220000196bcfb, 0xbfe07dc333828d0b, 0x3fe83a39eeb54b5a, 0x3fd4c76877223817, 0xbf7640237a6d6d30, 0xbfc02ca3ba99f440, 0xbfb58ef39ecd5000),
+	(0x3fe2400003756189, 0xbfe095f30afdbac3, 0x3fe825720fa6bb7d, 0x3fd4c8432598c0d4, 0xbf6c6d60d75bea04, 0xbfbfed5cd887c340, 0xbfb59454d68b4000),
+	(0x3fe26000013bdd1f, 0xbfe0ae0e172710bb, 0x3fe810a9889533b2, 0x3fd4c8be047e8fed, 0xbf5920e914dd15b8, 0xbfbf8160d625d180, 0xbfb597b64277d000),
+	(0x3fe28000026e7197, 0xbfe0c6145d2dc8dc, 0x3fe7fbe0b3cc857c, 0x3fd4c8da57d785da, 0x3f38b3db2033b920, 0xbfbf155d1d93f540, 0xbfb59923618c3000),
+	(0x3fe29ffffe4c855d, 0xbfe0de05d6652674, 0x3fe7e717f4e58b05, 0x3fd4c899639f2b70, 0x3f6287693d7864dc, 0xbfbea95b5bb7e400, 0xbfb598a7b4b93000),
+	(0x3fe2bfffffef534f, 0xbfe0f5e28b5b78df, 0x3fe7d24fa150837b, 0x3fd4c7fc6b9c5931, 0x3f70e125b375ae70, 0xbfbe3fedafd71237, 0xbfb596b5c99673e4),
+	(0x3fe2e000002e77a2, 0xbfe10daa7752f342, 0x3fe7bd8819154572, 0x3fd4c704b3dfd892, 0x3f7863a555ac2266, 0xbfbdd40f01365dd6, 0xbfb5928aaeb4bdf7),
+	(0x3fe2fffffd7c9d64, 0xbfe1255d9a2022cc, 0x3fe7a8c1b753a014, 0x3fd4c5b3801f820e, 0x3f7fcb39853a1bb2, 0xbfbd65bd8613d740, 0xbfb58c32edd58000),
+	(0x3fe31ffffd82cc9f, 0xbfe13cfbf94585b2, 0x3fe793fcd1396a06, 0x3fd4c40a1333413b, 0x3f838becc98b0eda, 0xbfbcfa1e649f96c0, 0xbfb5848705fe2000),
+	(0x3fe34000020760dc, 0xbfe1548597b4c2f9, 0x3fe77f39bd37da50, 0x3fd4c209afca8f6f, 0x3f8724ccc6f52d4f, 0xbfbc8ead87d86800, 0xbfb57b2bb11af000),
+	(0x3fe35fffffb1e89e, 0xbfe16bfa6f18133e, 0x3fe76a78d9002ba2, 0x3fd4bfb398e809ba, 0x3f8ab041c34cb79c, 0xbfbc23734d502d00, 0xbfb5702c550c2000),
+	(0x3fe37fffffa9dc9d, 0xbfe1835a887fabe0, 0x3fe755ba73b51888, 0x3fd4bd090f92bb18, 0x3f8e2e5415de4536, 0xbfbbb877951c57c0, 0xbfb5639444c5d000),
+	(0x3fe39fffffefd1ad, 0xbfe19aa5e51ddd70, 0x3fe740fee2743c7b, 0x3fd4ba0b54cf55f0, 0x3f90cf85e930af26, 0xbfbb4dc22c569940, 0xbfb5556ec8357000),
+	(0x3fe3bffffd025245, 0xbfe1b1dc8565ca41, 0x3fe72c467a13e900, 0x3fd4b6bba90e7725, 0x3f928138ee4f6ff2, 0xbfbae35aacf0e740, 0xbfb545c718118000),
+	(0x3fe3dffffcd8d6cc, 0xbfe1c8fe70fb7e35, 0x3fe717918808a566, 0x3fd4b31b4adbcf04, 0x3f942c4883ade35b, 0xbfba794859a0afc0, 0xbfb534a856177000),
+	(0x3fe3fffffd8e408d, 0xbfe1e00baa1d04da, 0x3fe702e05d9ffa6f, 0x3fd4af2b7871ca67, 0x3f95d0b7b3fb36e7, 0xbfba123e6124474e, 0xbfb522811fd8a133),
+	(0x3fe42000006e901a, 0xbfe1f70435a64d9d, 0x3fe6ee3348d92b91, 0x3fd4aaed6edf3dea, 0x3f976e91566dba37, 0xbfb9a8ef06a89b9d, 0xbfb50e94ff1867d4),
+	(0x3fe4400000a09097, 0xbfe20de8145acaa5, 0x3fe6d98a9a6f0264, 0x3fd4a6626ab55f2a, 0x3f9905db9ee4b8fd, 0xbfb93d56b7355c80, 0xbfb4f8efe7802000),
+	(0x3fe4600001861467, 0xbfe224b74d32a769, 0x3fe6c4e69c8fc28a, 0x3fd4a18ba5fdcca6, 0x3f9a9698b458c01f, 0xbfb8d4de4a82d700, 0xbfb4e262aeb99000),
+	(0x3fe47fffff909a16, 0xbfe23b71e27da2af, 0x3fe6b0479ca9c160, 0x3fd49c6a5abcf1e6, 0x3f9c20d20d8f992c, 0xbfb86cdc97970200, 0xbfb4ca94d76a4000),
+	(0x3fe49fffffb90e67, 0xbfe25217dce5c5c4, 0x3fe69bade1736aaf, 0x3fd496ffc020ed51, 0x3f9da48f8358d98f, 0xbfb805579f80a400, 0xbfb4b190f53f0000),
+	(0x3fe4c00000128cd2, 0xbfe268a940767cc7, 0x3fe68719b4de44dd, 0x3fd4914d0cf6c50f, 0x3f9f21d8f8715491, 0xbfb79e5545549d80, 0xbfb4976184a36000),
+	(0x3fe4dfffff3e5755, 0xbfe27f2611ebf889, 0x3fe6728b5f498085, 0x3fd48b53767a07ea, 0x3fa04c5b59e2627a, 0xbfb737db36653c00, 0xbfb47c10e4598000),
+	(0x3fe500000148f840, 0xbfe2958e5a167f56, 0x3fe65e032465797a, 0x3fd485142f44c956, 0x3fa10498ca140c07, 0xbfb6d1eedb71be40, 0xbfb45fa94fe02000),
+	(0x3fe52000018790be, 0xbfe2abe21bef8766, 0x3fe649814c4855c7, 0x3fd47e9069f4e9e3, 0x3fa1b9a9349c106a, 0xbfb66c95866404c0, 0xbfb44234ea994000),
+	(0x3fe540000064c499, 0xbfe2c2215e483288, 0x3fe635061a93197b, 0x3fd477c956655f3a, 0x3fa26b9005b791fd, 0xbfb60aa234b1e8ae, 0xbfb4241dc5417ce3),
+	(0x3fe5600002c99e32, 0xbfe2d84c2b4f57a0, 0x3fe62091ced9107e, 0x3fd470c021eda05c, 0x3fa31a54b048ef02, 0xbfb5a6812d9df714, 0xbfb404ad3b9865e5),
+	(0x3fe5800000512c22, 0xbfe2ee62843eb8ef, 0x3fe60c24b0014185, 0x3fd46975facafcfc, 0x3fa3c5fc054af685, 0xbfb5402d421a8b40, 0xbfb3e3ee1a090000),
+	(0x3fe5a0000334351e, 0xbfe30464776e19ff, 0x3fe5f7bef7e40401, 0x3fd461ec08f203ca, 0x3fa46e88d0626c5c, 0xbfb4dd50a5475c80, 0xbfb3c2a9098b8000),
+	(0x3fe5bffffe315006, 0xbfe31a52034bf998, 0x3fe5e360ee28562d, 0x3fd45a23782bc020, 0x3fa51401526e2908, 0xbfb47b1e8f091a80, 0xbfb3a087d2364000),
+	(0x3fe5e00000a1545d, 0xbfe3302b3a257b83, 0x3fe5cf0ac716d488, 0x3fd4521d6b4842ab, 0x3fa5b66b3eb3bc3a, 0xbfb4199af14bd180, 0xbfb37d93b34fe000),
+	(0x3fe5ffffff69b013, 0xbfe345f01c682620, 0x3fe5babcc6a742c0, 0x3fd449db09841112, 0x3fa655cbe07609ee, 0xbfb3b8c9e12c1d00, 0xbfb359d5e3704000),
+	(0x3fe61fffffac056a, 0xbfe35ba0b5d5fb7f, 0x3fe5a677255bb094, 0x3fd4415d73f9ab8d, 0x3fa6f228f4a18aac, 0xbfb358af15142d80, 0xbfb3355762050000),
+	(0x3fe63ffffff36e95, 0xbfe3713d0dee4c27, 0x3fe5923a1ec404b6, 0x3fd438a5cb4c88be, 0x3fa78b88346f22ca, 0xbfb2f94e2b0e0300, 0xbfb310210f69a000),
+	(0x3fe6600002e268dc, 0xbfe386c52f2da1f4, 0x3fe57e05eabaaeda, 0x3fd42fb52cd4f99a, 0x3fa821ef88cc1c46, 0xbfb29aaa894e96c0, 0xbfb2ea3ba114c000),
+	(0x3fe67ffffca43b52, 0xbfe39c391a94c1f4, 0x3fe569dac91c1aae, 0x3fd4268cb7b7c4c8, 0x3fa8b56360fbfb90, 0xbfb23fb635b482a9, 0xbfb2c40c5aced0ef),
+	(0x3fe6a0000087414b, 0xbfe3b198e63c8377, 0x3fe555b8e509d4d9, 0x3fd41d2d803d48ce, 0x3fa945ecc8324226, 0xbfb1e29a04de9b6e, 0xbfb29ce1f03b462c),
+	(0x3fe6bffffca9ca2a, 0xbfe3c6e48f902296, 0x3fe541a07ff88a58, 0x3fd41398a2ef107f, 0x3fa9d3919aace755, 0xbfb1834f7d89ce40, 0xbfb274c5bef82000),
+	(0x3fe6e00003fa3010, 0xbfe3dc1c2cba5e80, 0x3fe52d91c323fcee, 0x3fd409cf2ee4f9e8, 0x3faa5e55c45b939a, 0xbfb127c00d4bf6c0, 0xbfb24c780da48000),
+	(0x3fe6fffffff5c5b2, 0xbfe3f13fb897d886, 0x3fe5198cf0b1cf1f, 0x3fd3ffd23dbec556, 0x3faae6408c051ffe, 0xbfb0ccfcbf6e6a40, 0xbfb223a49e696000),
+	(0x3fe71fffffa86b8e, 0xbfe4064f471d169e, 0x3fe50592322d092f, 0x3fd3f5a2db1bb316, 0x3fab6b589c6aa3fa, 0xbfb07307e1378480, 0xbfb1fa5329170000),
+	(0x3fe7400001ee24e8, 0xbfe41b4ae1b35499, 0x3fe4f1a1ba383080, 0x3fd3eb42151dc89b, 0x3fabeda46cf6c88a, 0xbfb019e3c81c74c0, 0xbfb1d08b51ab4000),
+	(0x3fe76000004807ad, 0xbfe430328e7a1ebd, 0x3fe4ddbbbdbb66b6, 0x3fd3e0b0f944ff81, 0x3fac6d2a725bb64f, 0xbfaf832565793f00, 0xbfb1a6549afec000),
+	(0x3fe7800000c376a9, 0xbfe445065bf8569b, 0x3fe4c9e068c4d1e4, 0x3fd3d5f08e7e91ba, 0x3face9f164bddc9a, 0xbfaed42d30818400, 0xbfb17bb64ef82000),
+	(0x3fe7a00000bb278d, 0xbfe459c65333fe05, 0x3fe4b60febc4560b, 0x3fd3cb01dc145c05, 0x3fad63ffe9117670, 0xbfae26e2c80dc580, 0xbfb150b79aec4000),
+	(0x3fe7bffffdb2e507, 0xbfe46e727d826a87, 0x3fe4a24a7607bef5, 0x3fd3bfe5e6b19c89, 0x3faddb5b54b3040c, 0xbfad816604197de2, 0xbfb125b8c8b0881c),
+	(0x3fe7e0000252f58a, 0xbfe4830aecddb00e, 0x3fe48e902dbec701, 0x3fd3b49dac459984, 0x3fae500eb957d5e6, 0xbfacd1650ee54e80, 0xbfb0f9b4d2d88000),
+	(0x3fe7fffffc963c19, 0xbfe4978fa0f7692e, 0x3fe47ae149c6e6d9, 0x3fd3a92a31ac4439, 0x3faec21c8e9fe30c, 0xbfac29381cb8a880, 0xbfb0cdbe52f5c000),
+	(0x3fe81ffffd933f52, 0xbfe4ac00b03b4c38, 0x3fe4673dea60cfe4, 0x3fd39d8c6d24080f, 0x3faf318d54f3de26, 0xbfab82c543a90280, 0xbfb0a1827562e000),
+	(0x3fe8400002a90411, 0xbfe4c05e248f2ba3, 0x3fe453a63af9e7a4, 0x3fd391c5592e5cad, 0x3faf9e67efa37f40, 0xbfaade0f0b5e4c00, 0xbfb075079e842000),
+	(0x3fe85ffffeda28ed, 0xbfe4d4a8017a21db, 0x3fe4401a6c55b7ff, 0x3fd385d5f1a3c88b, 0x3fb0045995221920, 0xbfaa3b17f114e780, 0xbfb048541a0ac000),
+	(0x3fe87ffffcb5e629, 0xbfe4e8de59a40615, 0x3fe42c9a9fd97bd7, 0x3fd379bf270aa8eb, 0x3fb0383b14344703, 0xbfa999e1bc66d880, 0xbfb01b6deb596000),
+	(0x3fe8a0000170c515, 0xbfe4fd013c656e86, 0x3fe41926f94766d6, 0x3fd36d81e923c791, 0x3fb06adc00899d63, 0xbfa8fa6e1683e780, 0xbfafdcb5ebc98000),
+	(0x3fe8c0000013189d, 0xbfe51110add1e051, 0x3fe405bfa67ab9da, 0x3fd3611f2c074f8a, 0x3fb09c3fcc701a50, 0xbfa85cbec910c700, 0xbfaf82421fc08000),
+	(0x3fe8dffffea5a4e4, 0xbfe5250cbe1a044e, 0x3fe3f264c8d246d0, 0x3fd35497d9e7b6f1, 0x3fb0cc6a0b4acaae, 0xbfa7c0d506895100, 0xbfaf278b9c710000),
+	(0x3fe8fffffff532e7, 0xbfe538f57b82510b, 0x3fe3df1682be020a, 0x3fd347ecdb613f48, 0x3fb0fb5d96a0b379, 0xbfa72d0add537aa4, 0xbfaecd493ac67089),
+	(0x3fe9200000e0371d, 0xbfe54ccaf0c0e17a, 0x3fe3cbd4f95a3d43, 0x3fd33b1f192ca5ae, 0x3fb129201bd9bcf5, 0xbfa68e563bf5ca00, 0xbfae7181cd9f0000),
+	(0x3fe93ffffed17bb8, 0xbfe5608d290c9c45, 0x3fe3b8a0508476b6, 0x3fd32e2f7884690d, 0x3fb155b3032aa8fb, 0xbfa5f7c2e4e4cd80, 0xbfae16438ba38000),
+	(0x3fe95fffffb19d46, 0xbfe5743c34fb13c6, 0x3fe3a578a61f34cc, 0x3fd3211ed8f518b9, 0x3fb1811a9c607ce3, 0xbfa562f8391c6200, 0xbfadbaec7dd30000),
+	(0x3fe9800001fbd6cc, 0xbfe587d820a9ca1d, 0x3fe3925e1ba3c385, 0x3fd313ee1a3ddcff, 0x3fb1ab5a76e24f11, 0xbfa4cff68dc4ae00, 0xbfad5f866b46c000),
+	(0x3fe9a000028625b6, 0xbfe59b60f7595cc7, 0x3fe37f50d2a59cb4, 0x3fd3069e1a26c510, 0x3fb1d47620a6ae76, 0xbfa43ebe0fa40580, 0xbfad041ad7158000),
+	(0x3fe9c0000013e88f, 0xbfe5aed6c59caa8f, 0x3fe36c50eab346d4, 0x3fd2f92fb30656ff, 0x3fb1fc712a84e7c4, 0xbfa3af4eb4269c00, 0xbfaca8b2f6dac000),
+	(0x3fe9e00000c59ba9, 0xbfe5c2399c9bbead, 0x3fe3595e7e2616dd, 0x3fd2eba3b9686805, 0x3fb2234f2e03dca7, 0xbfa321a82363d200, 0xbfac4d57a3e34000),
+	(0x3fe9ffffff9af828, 0xbfe5d58986d9bfee, 0x3fe34679ad1b9f34, 0x3fd2ddfb03da55d4, 0x3fb24913b63c63f4, 0xbfa295ca0bd98800, 0xbfabf211910ac000),
+	(0x3fea1ffffe6f5c7c, 0xbfe5e8c6931fdc41, 0x3fe333a292cda05f, 0x3fd2d036635848cf, 0x3fb26dc255bbabd0, 0xbfa20bb3d390e000, 0xbfab96e9186cc000),
+	(0x3fea3ffffddba306, 0xbfe5fbf0cf8e022d, 0x3fe320d94a65b14d, 0x3fd2c256a69b9f29, 0x3fb2915ddee0c8a5, 0xbfa189f836ccd898, 0xbfab3c8bd862fbc5),
+	(0x3fea5ffffe550ddd, 0xbfe60f084a48a440, 0x3fe30e1dee5569d2, 0x3fd2b45c9a3476c6, 0x3fb2b3ec17359215, 0xbfa0fcdbe6e84800, 0xbfaae111172ec000),
+	(0x3fea800000e4f98f, 0xbfe6220d11e54f19, 0x3fe2fb7097ede8aa, 0x3fd2a64907194c54, 0x3fb2d56e5363f0a3, 0xbfa07818437a3900, 0xbfaa8670f6f14000),
+	(0x3fea9ffffda78430, 0xbfe634ff2fca48bb, 0x3fe2e8d164e983b8, 0x3fd2981cb8011622, 0x3fb2f5e8d1d6530f, 0xbf9fea318f2ad100, 0xbfaa2c0d5c400000),
+	(0x3feac00000a7650e, 0xbfe647deb944952c, 0x3fe2d64066a2b0d9, 0x3fd289d86c0d2d1b, 0x3fb3155f2583e8e6, 0xbf9ee7b7e4800000, 0xbfa9d1ed38234000),
+	(0x3feadffffedf751c, 0xbfe65aabb61747e5, 0x3fe2c3bdbb183012, 0x3fd27b7ce9f8bb53, 0x3fb333d4c786c2ea, 0xbf9de8c0fc5ad200, 0xbfa978177dbb8000),
+	(0x3feafffffd65ea17, 0xbfe66d66379ec9f1, 0x3fe2b149762e2d21, 0x3fd26d0aeeb178ab, 0x3fb3514d3de8eaea, 0xbf9ced4987a4d100, 0xbfa91e92b3a98000),
+	(0x3feb200000caf460, 0xbfe6800e4ef44188, 0x3fe29ee3ab610acd, 0x3fd25e8334b45cff, 0x3fb36dcc0a58c590, 0xbf9bf54dfdf31300, 0xbfa8c56525bc0000),
+	(0x3feb4000000e26ac, 0xbfe692a4055f2f52, 0x3fe28c8c753d776e, 0x3fd24fe67a0bb733, 0x3fb389549efd4d08, 0xbf9b00cb02862100, 0xbfa86c9508b40000),
+	(0x3feb6000018849cd, 0xbfe6a5276d2d89d2, 0x3fe27a43e4c58f7d, 0x3fd24135732df900, 0x3fb3a3ea77d68263, 0xbf9a0fbc87055500, 0xbfa814282ba74000),
+	(0x3feb8000010d9519, 0xbfe6b79892a64df0, 0x3fe2680a104c3459, 0x3fd23270d6aa460d, 0x3fb3bd90404e0eb5, 0xbf992fb610f8b7a1, 0xbfa7bcc387688703),
+	(0x3feb9ffffe599af5, 0xbfe6c9f7846a2b45, 0x3fe255df0b3288ee, 0x3fd22399572c6060, 0x3fb3d64bb1660697, 0xbf9837ece0652d00, 0xbfa7648eb5fe0000),
+	(0x3febc00000284356, 0xbfe6dc44552c4ed1, 0x3fe243c2e433adbd, 0x3fd214afa0d6b3b1, 0x3fb3ee1def591e9a, 0xbf975122b84b5a00, 0xbfa70d6caea6c000),
+	(0x3febdffffe085993, 0xbfe6ee7f0f01eeef, 0x3fe231b5b1f500b7, 0x3fd205b464c5bfb6, 0x3fb4050b1cb5f2a6, 0xbf966dbba68c0400, 0xbfa6b6c3404c0000),
+	(0x3fec0000034fb3e6, 0xbfe700a7c7586398, 0x3fe21fb77f46182c, 0x3fd1f6a8482e18b6, 0x3fb41b16a1f46d60, 0xbf958db278506e00, 0xbfa66097156f0000),
+	(0x3fec1ffffdfe62e8, 0xbfe712be83078c02, 0x3fe20dc866cc799f, 0x3fd1e78bfb883685, 0x3fb43043ce52cf56, 0xbf94b1029a5ec700, 0xbfa60aecf2b30000),
+	(0x3fec3fffff94c963, 0xbfe724c35b136d78, 0x3fe1fbe86e98a7b2, 0x3fd1d8601c0fd209, 0x3fb4449603e9797b, 0xbf93d7a656cf6400, 0xbfa5b5c9094d0000),
+	(0x3fec60000082bdf4, 0xbfe736b65a605f56, 0x3fe1ea17aa267316, 0x3fd1c92550541ec4, 0x3fb458108eb64abd, 0xbf9301987b6f8700, 0xbfa5612f9c3b8000),
+	(0x3fec800000df6764, 0xbfe748979037234f, 0x3fe1d85628043564, 0x3fd1b9dc38ce0a23, 0x3fb46ab6ba64e101, 0xbf922ed378f00200, 0xbfa50d24a7678000),
+	(0x3fec9fffff08b5c1, 0xbfe75a670af97a58, 0x3fe1c6a3f714bf96, 0x3fd1aa8574538e0f, 0x3fb47c8bcc0c4e1c, 0xbf915f51a50a7500, 0xbfa4b9abfb4dc000),
+	(0x3fecbfffff264192, 0xbfe76c24dc4e49f1, 0x3fe1b501226bbf38, 0x3fd19b219c625478, 0x3fb48d923c79c7f8, 0xbf90a110cf52e4ae, 0xbfa4676263f4c032),
+	(0x3fece00000316893, 0xbfe77dd113055eab, 0x3fe1a36db76194ae, 0x3fd18bb14affb17d, 0x3fb49dcfa250598d, 0xbf8f93ff72a6f600, 0xbfa4147fa51d0000),
+	(0x3fed0000028a12de, 0xbfe78f6bbec21f96, 0x3fe191e9c1f0e9ca, 0x3fd17c351662872d, 0x3fb4ad44d4d39570, 0xbf8e08471e932a00, 0xbfa3c2d2ad154000),
+	(0x3fed200003373601, 0xbfe7a0f4ed5e56f4, 0x3fe180754f521d39, 0x3fd16cad947835ea, 0x3fb4bbf5ca4e213b, 0xbf8c82e4ca8e1c00, 0xbfa371c55ec44000),
+	(0x3fed400000e2fa29, 0xbfe7b26cada9f9ab, 0x3fe16f106b412869, 0x3fd15d1b57e6e3de, 0x3fb4c9e5aa0c4652, 0xbf8b03cbd541a800, 0xbfa3215aa7d68000),
+	(0x3fed5ffffc647157, 0xbfe7c3d30fb0d432, 0x3fe15dbb1fb975b9, 0x3fd14d7eefeac143, 0x3fb4d71795f22c94, 0xbf898aef4bb08a00, 0xbfa2d19546608000),
+	(0x3fed8000030878d4, 0xbfe7d5282a436004, 0x3fe14c756f72ef0b, 0x3fd13dd8e34e747c, 0x3fb4e38eae04b3a6, 0xbf881841786e0000, 0xbfa28277b07e0000),
+	(0x3feda0000038b7ba, 0xbfe7e66c01df9f9b, 0x3fe13b3f6ee50309, 0x3fd12e29c71cae76, 0x3fb4ef4dfe6e2bfe, 0xbf86abb5fe255e00, 0xbfa2340488c34000),
+	(0x3fedc000024cc650, 0xbfe7f79eadf54885, 0x3fe12a191f2548cb, 0x3fd11e721cfd633f, 0x3fb4fa589a26b592, 0xbf85453ebe0b9e00, 0xbfa1e63df3f04000),
+	(0x3fede000009d89d2, 0xbfe808c0399495a2, 0x3fe119028d1fda26, 0x3fd10eb26f95f279, 0x3fb504b184ed26c3, 0xbf83e4ce746a9e00, 0xbfa1992629544000),
+	(0x3fee00000039743a, 0xbfe819d0b7341e61, 0x3fe107fbbde28c9e, 0x3fd0feeb406dd82e, 0x3fb50e5af0d5593e, 0xbf82a72ef1e0c167, 0xbfa14d527b168f8a),
+	(0x3fee1ffffe5cc00a, 0xbfe82ad03521bbb6, 0x3fe0f704ba259f97, 0x3fd0ef1d13273fc2, 0x3fb5175a44a65f21, 0xbf8135cae0939400, 0xbfa1010aa6568000),
+	(0x3fee4000019b115b, 0xbfe83bbec6a702d7, 0x3fe0e61d852e5196, 0x3fd0df4863d03473, 0x3fb51fb00570e1c7, 0xbf7fce36d18fd400, 0xbfa0b60a74c20000),
+	(0x3fee5ffffdf4f7e1, 0xbfe84c9c7540d5f2, 0x3fe0d5462b922e3d, 0x3fd0cf6db5f37b20, 0x3fb5275fea93680c, 0xbf7d3c75fad99000, 0xbfa06bc035858000),
+	(0x3fee80000323ee64, 0xbfe85d6959120279, 0x3fe0c47eaad03167, 0x3fd0bf8d7d13d57e, 0x3fb52e6cdb8a684c, 0xbf7ab635583b0400, 0xbfa0222d3764c000),
+	(0x3feea000027f9467, 0xbfe86e257a464e49, 0x3fe0b3c70fe40a0e, 0x3fd0afa8399b9a17, 0x3fb534d9b198efb2, 0xbf783b593b7d2000, 0xbf9fb2a5de1a8000),
+	(0x3feec000016d28f0, 0xbfe87ed0eb9a3410, 0x3fe0a31f5cc9486a, 0x3fd09fbe5fe0dff2, 0x3fb53aa9435bdcf3, 0xbf75cbc42e130c00, 0xbf9f226507280000),
+	(0x3feee0000186b339, 0xbfe88f6bbdcc87be, 0x3fe092879506eb54, 0x3fd08fd063fd06b3, 0x3fb53fde5f2950c0, 0xbf736758dd6aac00, 0xbf9e939a0cb08000),
+	(0x3feeffffffce4723, 0xbfe89ff5ff3e4b8a, 0x3fe081ffbe119e2e, 0x3fd07fdeba3b0de8, 0x3fb5447bcb488540, 0xbf710dfa27bda400, 0xbf9e0646ebfc0000),
+	(0x3fef20000017d916, 0xbfe8b06fc1db7f25, 0x3fe07187d965874a, 0x3fd06fe9d16dfdc9, 0x3fb5488447a9ed9c, 0xbf6d7f1490008000, 0xbf9d7a6d4a5b0000),
+	(0x3fef3ffffe33911c, 0xbfe8c0d9137147b0, 0x3fe0611fec30af7f, 0x3fd05ff21a3a42d4, 0x3fb54bf9b699774b, 0xbf696e589b06ec6f, 0xbf9cf12a32a34060),
+	(0x3fef5ffffe084599, 0xbfe8d13205f7eff9, 0x3fe050c7f70b73f8, 0x3fd04ff7ffb69502, 0x3fb54ee148abcb5e, 0xbf648602474d4800, 0xbf9c672c6e7a8000),
+	(0x3fef7ffffdfbe7bb, 0xbfe8e17aa896a3fa, 0x3fe0407ffcf5ee0b, 0x3fd03ffbecf3660f, 0x3fb5513b2748a2d9, 0xbf6029586a500800, 0xbf9bdfc7884c0000),
+	(0x3fef9fffff0fa180, 0xbfe8f1b30bcb577c, 0x3fe03047ff31c004, 0x3fd02ffe4a3a5b50, 0x3fb5530ac95cb722, 0xbf57c33cda611000, 0xbf9b59e0e3a28000),
+	(0x3fefc00001a24bf4, 0xbfe901db3fc1bb6f, 0x3fe0201ffeecb132, 0x3fd01fff7e0f13c7, 0x3fb55452c9166f13, 0xbf4eba61be0c4000, 0xbf9ad57931778000),
+	(0x3fefdfffffe38639, 0xbfe911f3518b3813, 0x3fe01008000a410c, 0x3fd00ffff01bf387, 0x3fb55515b9099fdd, 0xbf3c805a37250000, 0xbf9a52910b908000),
+	(0x3feff0000008727f, 0xbfe919f953f31326, 0x3fe00801fffb8473, 0x3fd007fffdfb4766, 0x3fb555453ecbbd3f, 0xbf30045a21318845, 0xbf9a12c2520fd1de),
+]
+
+const atan32 = {x
+	var r = atan264((x : flt64), 1.0)
+	-> (r : flt32)
+}
+
+const atan64 = {x
+	-> atan264(x, 1.0)
+}
+
+const atan232 = {y, x
+	var r = atan264((y : flt64), (x : flt64))
+	-> (r : flt32)
+}
+
+const atan264 = {y, x
+	if std.isnan(y) || std.isnan(x)
+		-> std.flt64nan()
+	;;
+
+	var xabs = std.flt64frombits(std.flt64bits(x) & (~(0 : uint64)) >> 1)
+	var yabs = std.flt64frombits(std.flt64bits(y) & (~(0 : uint64)) >> 1)
+
+	var xb = std.flt64bits(x)
+	if xb == 0x0 || xb == 0x8000000000000000
+		if (y >= 0.0) == (x >= 0.0)
+			-> std.flt64frombits(0x3ff921fb54442d18)
+		else
+			-> std.flt64frombits(0xbff921fb54442d18)
+		;;
+	;;
+
+	var then_reverse = false
+	if yabs > xabs
+		then_reverse = true
+		std.swap(&x, &y)
+	;;
+
+	/* Compute y/x = u + du; du is one Newton's iteration of division */
+	var u = y / x
+	var t1, t2
+	(t1, t2) = two_by_two(u, x)
+	var du = u * ((1.0 - t1) - t2)
+
+	var ret = atan_reduced(u, du)
+
+	if then_reverse
+		/* Compute pi/2 - ret; pi_over_2 is in sin-impl.myr */
+		var po2_hi = std.flt64frombits(pi_over_2[0])
+		var po2_lo = std.flt64frombits(pi_over_2[1])
+		ret = (po2_hi - ret) + po2_lo
+	;;
+
+	-> ret
+}
+
+/* Handle arctan(z) with z in (-1, 1) */
+const atan_reduced = {u : flt64, du : flt64
+	var then_negate : bool = false
+	var ret : flt64
+
+	if u < 0.0
+		then_negate = true
+		u = -1.0 * u
+		du = -1.0 * du
+	;;
+
+	/*
+	   If u is less than 1/16, [GB91] uses a single polynomial
+	   approximation. I am not quite sure why they don't employ
+	   tables in this case: the speed appears to be about the
+	   same. Perhaps to save a few bits for the first entries
+	   of the table?
+	 */
+	if u <  0.0625
+		var s = u * u
+		var p = horner_polyu(s, atan_coeffs[:])
+		ret = u*p + du
+		goto have_result
+	;;
+
+	/*
+	   Extract a polynomial from the table.
+	 */
+	var j = rn(scale2(u, 8))
+	if j < 0
+		j = 0
+	elif j > 256
+		j = 256
+	;;
+
+	var xi_u : uint64, c : uint64[6]
+	(xi_u, c[0], c[1], c[2], c[3], c[4], c[5]) = C[j]
+	var xi : flt64 = std.flt64frombits(xi_u)
+
+	ret = horner_polyu((u - xi) + du, c[:])
+
+:have_result
+
+	if then_negate
+		ret = -1.0 * ret
+	;;
+
+	-> ret
+}
--- a/lib/math/bld.sub
+++ b/lib/math/bld.sub
@@ -1,12 +1,15 @@
 lib math =
 	fpmath.myr
 
-	# exp and expm1
-	exp-impl.myr
-
 	# rounding (to actual integers)
 	round-impl+posixy-x64-sse4.s
 	round-impl.myr
+
+	# atan and atan2
+	atan-impl.myr
+
+	# exp and expm1
+	exp-impl.myr
 
 	# fused-multiply-add
 	fma-impl+posixy-x64-fma.s
--- a/lib/math/fpmath.myr
+++ b/lib/math/fpmath.myr
@@ -3,6 +3,10 @@
 pkg math =
 	trait fpmath @f =
 
+		/* atan-impl */
+		atan : (x : @f -> @f)
+		atan2 : (y : @f, x : @f -> @f)
+
 		/* exp-impl */
 		exp : (x : @f -> @f)
 		expm1 : (x : @f -> @f)
@@ -84,6 +88,9 @@
 ;;
 
 impl fpmath flt32 =
+	atan = {x; -> atan32(x)}
+	atan2 = {y, x; -> atan232(y, x)}
+
 	fma = {x, y, z; -> fma32(x, y, z)}
 
 	exp = {x; -> exp32(x)}
@@ -118,6 +125,9 @@
 ;;
 
 impl fpmath flt64 =
+	atan = {x; -> atan64(x)}
+	atan2 = {y, x; -> atan264(y, x)}
+
 	fma = {x, y, z; -> fma64(x, y, z)}
 
 	exp = {x; -> exp64(x)}
@@ -152,6 +162,12 @@
 
 extern const rn32 : (x : flt32 -> int32)
 extern const rn64 : (x : flt64 -> int64)
+
+extern const atan32 : (x : flt32 -> flt32)
+extern const atan64 : (x : flt64 -> flt64)
+
+extern const atan232 : (y : flt32, x : flt32 -> flt32)
+extern const atan264 : (y : flt64, x : flt64 -> flt64)
 
 extern const fma32 : (x : flt32, y : flt32, z : flt32 -> flt32)
 extern const fma64 : (x : flt64, y : flt64, z : flt64 -> flt64)
--- a/lib/math/sin-impl.myr
+++ b/lib/math/sin-impl.myr
@@ -58,10 +58,12 @@
 
 	pkglocal const trig_reduce : (x : flt64 -> (int64, flt64, flt64))
 	pkglocal const trig_table_approx : (x1 : flt64, C : (uint64, uint64, uint64)[257] -> (uint64, uint64, uint64))
+
+	pkglocal const pi_over_2 : uint64[4]
 ;;
 
 /* Pi/2 in lots of detail, for range reducing sin(2^18) or so */
-const pi_over_2 : uint64[4] = [
+const pi_over_2 = [
 	0x3ff921fb54442d18,
 	0x3c91a62633145c07,
 	0xb91f1976b7ed8fbc,