ref: 655dad8f92c315c5c205b3c021b19ce2916e4c9b
dir: /lib/math/test/exp-impl.myr/
use std use math use testr /* Note: a major part of the algorithms are the S constants. They are tested extensively in expm101 and expm102. */ const main = { math.fptrap(false) testr.run([ [.name="exp-01", .fn = exp01], [.name="exp-02", .fn = exp02], [.name="exp-03", .fn = exp03], [.name="exp-04", .fn = exp04], [.name="expm1-01", .fn = expm101], [.name="expm1-02", .fn = expm102], [.name="expm1-03", .fn = expm103], [.name="expm1-04", .fn = expm104], ][:]) } const exp01 = {c var inputs : (uint32, uint32)[:] = [ (0x00000000, 0x3f800000), (0x34000000, 0x3f800001), (0x3c000000, 0x3f810101), (0x42000000, 0x568fa1fe), (0xc2b00000, 0x0041edc4), (0xc2b20000, 0x001840fc), (0x7f7fffff, 0x7f800000), (0x7f800000, 0x7f800000), (0x7f800001, 0x7fc00000), (0xc2cff1b3, 0x00000001), (0xc2cff1b4, 0x00000001), (0xc2cff1b5, 0000000000), (0x42b17217, 0x7f7fff84), (0x42b17218, 0x7f800000), (0x42b17219, 0x7f800000), ][:] for (x, y) : inputs var xf : flt32 = std.flt32frombits(x) var yf : flt32 = std.flt32frombits(y) var rf = math.exp(xf) testr.check(c, rf == yf, "exp(0x{b=16,w=8,p=0}) should be 0x{b=16,w=8,p=0}, was 0x{b=16,w=8,p=0}", x, y, std.flt32bits(rf)) ;; } const exp02 = {c var inputs : (uint64, uint64)[:] = [ (0x0000000000000000, 0x3ff0000000000000), (0x3e50000000000000, 0x3ff0000004000000), ][:] for (x, y) : inputs var xf : flt64 = std.flt64frombits(x) var yf : flt64 = std.flt64frombits(y) var rf = math.exp(xf) testr.check(c, rf == yf, "exp(0x{b=16,w=16,p=0}) should be 0x{b=16,w=16,p=0}, was 0x{b=16,w=16,p=0}", x, y, std.flt64bits(rf)) ;; } const exp03 = {c /* Tang's algorithm has an error of up to 0.77 ulps. This is not terrible (musl appears to follow it, for example). Here we quarantine off some known-bad results. */ var inputs : (uint32, uint32, uint32)[:] = [ (0x42020000, 0x56eccf79, 0x56eccf78), (0x3ec40600, 0x3fbbb54b, 0x3fbbb54c), ][:] for (x, y_perfect, y_acceptable) : inputs var xf : flt32 = std.flt32frombits(x) var ypf : flt32 = std.flt32frombits(y_perfect) var yaf : flt32 = std.flt32frombits(y_acceptable) var rf = math.exp(xf) if rf != ypf && rf != yaf testr.fail(c, "exp(0x{b=16,w=8,p=0}) was 0x{b=16,w=8,p=0}. It should have been 0x{b=16,w=8,p=0}, although we will also accept 0x{b=16,w=8,p=0}", x, std.flt32bits(rf), y_perfect, y_acceptable) ;; ;; } const exp04 = {c /* Tang's algorithm has an error of up to 0.77 ulps. This is not terrible (musl appears to follow it, for example). Here we quarantine off some known-bad results. */ var inputs : (uint64, uint64, uint64)[:] = [ (0x3cda000000000000, 0x3ff0000000000006, 0x3ff0000000000007), (0x3d57020000000000, 0x3ff00000000005c0, 0x3ff00000000005c1), (0x3d58020000000000, 0x3ff0000000000600, 0x3ff0000000000601), (0xc087030000000000, 0x0000000000000c6d, 0x0000000000000c6e), (0xc011070000000000, 0x3f8d039e34c59187, 0x3f8d039e34c59186), (0xbd50070000000000, 0x3feffffffffff7fc, 0x3feffffffffff7fd), (0xbd430e0000000000, 0x3feffffffffffb3c, 0x3feffffffffffb3d), ][:] for (x, y_perfect, y_acceptable) : inputs var xf : flt64 = std.flt64frombits(x) var ypf : flt64 = std.flt64frombits(y_perfect) var yaf : flt64 = std.flt64frombits(y_acceptable) var rf = math.exp(xf) if rf != ypf && rf != yaf testr.fail(c, "exp(0x{b=16,w=16,p=0}) was 0x{b=16,w=16,p=0}. It should have been 0x{b=16,w=16,p=0}, although we will also accept 0x{b=16,w=16,p=0}", x, std.flt64bits(rf), y_perfect, y_acceptable) ;; ;; } const expm101 = {c var inputs : (uint32, uint32)[:] = [ (0x00000000, 0x00000000), (0x80000000, 0x80000000), (0x3f000000, 0x3f261299), (0x3c000000, 0x3c008056), (0x42000000, 0x568fa1fe), (0xc2b00000, 0xbf800000), (0xc2b20000, 0xbf800000), (0x01000000, 0x01000000), (0x40000000, 0x40cc7326), (0x42b17200, 0x7f7ff404), (0x415a3cf2, 0x494cd0e3), (0x7f800000, 0x7f800000), (0xff800000, 0xbf800000), (0x7a2028b1, 0x7f800000), (0xa201a23a, 0xa201a23a), (0xc0000000, 0xbf5d5aab), (0xbe934b10, 0xbe7fffff), (0xbe934b11, 0xbe800000), (0xbe934b12, 0xbe800001), (0x3e647fbe, 0x3e800000), (0x3e647fbf, 0x3e800000), (0x3e647fc0, 0x3e800001), (0xc0f744f5, 0xbf7fe31e), (0x4210297a, 0x597f31f5), /* J = 0 */ (0x3f34c3cd, 0x3f83573d), /* J = 1 */ (0x3f3a52b6, 0x3f89087b), /* J = 2 */ (0xbf20e72b, 0xbeeee940), /* ... */ (0x41f4bd2a, 0x558c999f), (0xc02a0418, 0xbf6e07cd), (0xc0293a2a, 0xbf6dcec1), (0x40b62779, 0x4393ca4b), (0x3fc680ac, 0x406dc6a4), (0x3fc9d2c6, 0x4075b516), (0xbfedd645, 0xbf581273), (0x3e70e5d1, 0x3e87cbdb), (0xbeddcacc, 0xbeb3ffd9), (0x3e8beb21, 0x3ea0e776), (0x3e9ded31, 0x3eb8fe1f), (0x40e8503c, 0x44b19ed8), (0x40d265cb, 0x4432f91f), (0xbea0f9bc, 0xbe8a2036), (0x3ec42672, 0x3eef04c4), (0xc140e8cc, 0xbf7fff9f), (0x4117320e, 0x46467e73), (0x3ee8b75d, 0x3f134ef0), (0xc03f51f1, 0xbf731e4e), (0x42733615, 0x6b52d3d4), (0x3f02f2b5, 0x3f2af617), (0xbf5ac925, 0xbf131660), (0x40813277, 0x425eb7ac), (0x41842e94, 0x4b64b1dd), (0x41b0ba81, 0x4f6a0cc1), (0xc061d7c2, 0xbf787d28), (0xc0611682, 0xbf786657), (0x40dcd7e9, 0x447827c5), /* J = 31 */ ][:] for (x, y) : inputs var xf : flt32 = std.flt32frombits(x) var yf : flt32 = std.flt32frombits(y) var rf = math.expm1(xf) testr.check(c, rf == yf, "expm1(0x{b=16,w=8,p=0}) should be 0x{b=16,w=8,p=0}, was 0x{b=16,w=8,p=0}", x, y, std.flt32bits(rf)) ;; } const expm102 = {c var inputs : (uint64, uint64)[:] = [ (0x0000000000000000, 0x0000000000000000), (0x404ef04831cb65ed, 0x45834ac37c44b3d3), (0x7ff0000000000000, 0x7ff0000000000000), (0xfff0000000000000, 0xbff0000000000000), (0x80318a89f290021a, 0x80318a89f290021a), (0xc0180881a9e73af6, 0xbfefebdcaf24d5fe), (0xc020cedaedb028c9, 0xbfeffe2a4ee5ba79), (0xbfe62812ff80cb9e, 0xbfdff9cf6758cc6a), /* J = 0 */ (0xbfe526dab7e5054c, 0xbfdef44fe4876d02), /* J = 1 */ (0x3ff6ea5c51cbf0f2, 0x400980f836e2c055), /* J = 2 */ (0x403f4315360b2cdc, 0x42c12ad5f692ffff), /* ... */ (0x3fe93f778a9dc013, 0x3ff3381168aca01e), (0x405023f373e01862, 0x45c1aa771de3ba9c), (0xbfff56366f3b92de, 0xbfeb7c693f8bdbb8), (0xc0159bcd07244a34, 0xbfefdb1461286124), (0x40079bbc23a67f90, 0x40322039bbbb5e2e), (0xbffe1933d2c0ed70, 0xbfeb1f6c166582bb), (0xc009ea7d09d84479, 0xbfeebf01fa92741c), (0x405d84f7563a2612, 0x4a946476fb27817e), (0x4045f770a45f8e7f, 0x43e4da111dae0dfb), (0x4070e9a83b352180, 0x585516d4e37bd9f6), (0x3fefcdb2a528c6e8, 0x3ffb39ec926d8a50), (0x3fd52b5e7995f00c, 0x3fd91739183464e0), (0xbfd625845bbaf98f, 0xbfd2b893d222b8f2), (0xbfd43c0407d114d5, 0xbfd15909a4bea38e), (0x3fd93f8288681821, 0x3fdef406a9f7c4b1), (0x3fdaad696fbfea76, 0x3fe08c8035acbd0b), (0x405e9b6f4b4bc7f3, 0x4af8b6ad079946a7), (0x3fdc85cf6b85bfaf, 0x3fe1f811193e5cf5), (0xbfed55f9b317d7eb, 0xbfe334b0378703a0), (0x406ee7f396a46c9b, 0x563a11333c75a10f), (0x4031266dc880810e, 0x417ac458c1525e64), (0xc019905c018b6d96, 0xbfeff243dffe774d), (0x404dc17e83d7ee6b, 0x454cfbf6572d627f), (0xc013dcd6fae06405, 0xbfefc6dfe34e5408), (0x402762d99fa5cfda, 0x40fd3b9a2004f68b), (0xbfe89074f132e353, 0xbfe12602fb3c9806), (0x4077c7ea24627ae7, 0x623ea61f88281bd5), (0xbff6a873237d8072, 0xbfe83c311800b6ee), /* J = 31 */ ][:] for (x, y) : inputs var xf : flt64 = std.flt64frombits(x) var yf : flt64 = std.flt64frombits(y) var rf = math.expm1(xf) testr.check(c, rf == yf, "expm1(0x{b=16,w=16,p=0}) should be 0x{b=16,w=16,p=0}, was 0x{b=16,w=16,p=0}", x, y, std.flt64bits(rf)) ;; } const expm103 = {c /* As with exp, there is some accepted error in expm1. */ var inputs : (uint32, uint32, uint32)[:] = [ (0x34000000, 0x34000001, 0x34000000), (0xbe651dea, 0xbe4d4b4d, 0xbe4d4b4c), ][:] for (x, y_perfect, y_acceptable) : inputs var xf : flt32 = std.flt32frombits(x) var ypf : flt32 = std.flt32frombits(y_perfect) var yaf : flt32 = std.flt32frombits(y_acceptable) var rf = math.expm1(xf) if rf != ypf && rf != yaf testr.fail(c, "expm1(0x{b=16,w=8,p=0}) was 0x{b=16,w=8,p=0}. It should have been 0x{b=16,w=8,p=0}, although we will also accept 0x{b=16,w=8,p=0}", x, std.flt32bits(rf), y_perfect, y_acceptable) ;; ;; } const expm104 = {c /* As with exp, there is some accepted error in expm1. */ var inputs : (uint64, uint64, uint64)[:] = [ (0xbf9d0b5aadc4d0ac, 0xbf9ca2e5b7bfa859, 0xbf9ca2e5b7bfa85a), (0x3fc2dbb101fe0392, 0x3fc451731cc0e358, 0x3fc451731cc0e359), (0x3fc8a39bc9c32fec, 0x3fcb2b988c3e0b2f, 0x3fcb2b988c3e0b30), ][:] for (x, y_perfect, y_acceptable) : inputs var xf : flt64 = std.flt64frombits(x) var ypf : flt64 = std.flt64frombits(y_perfect) var yaf : flt64 = std.flt64frombits(y_acceptable) var rf = math.expm1(xf) if rf != ypf && rf != yaf testr.fail(c, "expm1(0x{b=16,w=16,p=0}) was 0x{b=16,w=16,p=0}. It should have been 0x{b=16,w=16,p=0}, although we will also accept 0x{b=16,w=16,p=0}", x, std.flt64bits(rf), y_perfect, y_acceptable) ;; ;; }