tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

pow-approx.js (41463B)


      1 if (typeof fdlibm === "undefined") {
      2  var fdlibm = SpecialPowers.Cu.getJSTestingFunctions().fdlibm;
      3 }
      4 
      5 if (typeof getBuildConfiguration === "undefined") {
      6  var getBuildConfiguration = SpecialPowers.Cu.getJSTestingFunctions().getBuildConfiguration;
      7 }
      8 
      9 const f64 = new Float64Array(1);
     10 const ui64 = new BigUint64Array(f64.buffer);
     11 
     12 function toBits(n) {
     13  f64[0] = n;
     14  return ui64[0];
     15 }
     16 
     17 function errorInULP(actual, expected) {
     18  // Handle NaN and +0/-0.
     19  if (Object.is(actual, expected)) {
     20    return 0;
     21  }
     22 
     23  let x = toBits(actual);
     24  let y = toBits(expected);
     25  return x <= y ? Number(y - x) : Number(x - y);
     26 }
     27 
     28 // Test methodology:
     29 //
     30 // Generate test cases for inputs where the original js::powi implementation
     31 // returns a different result than std::pow. If such inputs where found, compare
     32 // them against fdlibm::pow to find inputs where the error is larger than 1 ULP.
     33 //
     34 // Compile with:
     35 // -std=c++17 -O3 -msse -msse2 -mfpmath=sse -fno-math-errno -fno-exceptions -fno-rtti -march=native
     36 //
     37 // static bool test(double x, int32_t y) {
     38 //   if (std::isnan(x)) {
     39 //     return true;
     40 //   }
     41 //
     42 //   double t = js::powi(x, y);
     43 //   double u = std::pow(x, static_cast<double>(y));
     44 //   if (t == u) {
     45 //     return true;
     46 //   }
     47 //
     48 //   uint64_t a;
     49 //   std::memcpy(&a, &t, sizeof(double));
     50 //
     51 //   uint64_t b;
     52 //   std::memcpy(&b, &u, sizeof(double));
     53 //
     54 //   double v = fdlibm::pow(x, y);
     55 //
     56 //   uint64_t c;
     57 //   std::memcpy(&c, &v, sizeof(double));
     58 //
     59 //   double w = musl::pow(x, y);
     60 //
     61 //   uint64_t d;
     62 //   std::memcpy(&d, &w, sizeof(double));
     63 //
     64 //   // Expect at most 1 ULP difference between std::pow and fdlibm::pow.
     65 //   if ((b < c && c - b > 1) || (b > c && b - c > 1)) {
     66 //     printf("!!! [fdlibm] %.53f ** %d: 0x%" PRIx64 " != 0x%" PRIx64 "\n", x, y, b, c);
     67 //     exit(1);
     68 //   }
     69 //
     70 //   // Expect at most 1 ULP difference between std::pow and musl::pow.
     71 //   if ((b < d && d - b > 1) || (b > d && b - d > 1)) {
     72 //     printf("!!! [musl] %.53f ** %d: 0x%" PRIx64 " != 0x%" PRIx64 "\n", x, y, b, d);
     73 //     exit(1);
     74 //   }
     75 //
     76 //   // Accept 1 ULP difference between js::powi and fdlibm::pow.
     77 //   if ((a <= c && c - a <= 1) || (a >= c && a - c <= 1)) {
     78 //     return true;
     79 //   }
     80 //
     81 //   // Output if a larger error was found.
     82 //   printf("%.53f ** %d: 0x%" PRIx64 " != 0x%" PRIx64 " (0x%" PRIx64 ") (0x%" PRIx64 ")\n", x, y, a, b, c, d);
     83 //   return false;
     84 // }
     85 //
     86 // int main() {
     87 //   // Use mt19937 for reproducible results.
     88 //   std::mt19937_64 gen64;
     89 //   std::mt19937 gen32;
     90 //
     91 //   for (uint64_t i = 0; i < 100'000'000'000; ++i) {
     92 //     uint64_t x = gen64();
     93 //     int32_t y = gen32();
     94 //
     95 //     double f;
     96 //     std::memcpy(&f, &x, sizeof(double));
     97 //
     98 //     test(f, y);
     99 //   }
    100 // }
    101 
    102 // Raw output:
    103 //
    104 // 0.99998738156596089776684266325901262462139129638671875 ** 38583256: 0x140854811fb319e7 != 0x140854811fe4d778 (0x140854811fe4d778) (0x140854811fe4d778)
    105 // -0.99843469603485224261874009243911132216453552246093750 ** 326215: 0x91dad4716de6fc4b != 0x91dad4716de5e587 (0x91dad4716de5e588) (0x91dad4716de5e587)
    106 // 0.00003722856305626354357250426541092735988058848306537 ** -33: 0x5e47357c3582e49e != 0x5e47357c3582e4a3 (0x5e47357c3582e4a3) (0x5e47357c3582e4a3)
    107 // -0.99996909838479330900895547529216855764389038085937500 ** 17078527: 0x9058409e5ea3b80a != 0x9058409e5eb11ef4 (0x9058409e5eb11ef4) (0x9058409e5eb11ef4)
    108 // 0.99992690642006631929206150743993930518627166748046875 ** -6725291: 0x6c42a167a8b7c0b2 != 0x6c42a167a8b81d0e (0x6c42a167a8b81d0e) (0x6c42a167a8b81d0e)
    109 // -0.99879181217764612110698863034485839307308197021484375 ** 485128: 0xb0d9c6f2f710d24 != 0xb0d9c6f2f71708d (0xb0d9c6f2f71708d) (0xb0d9c6f2f71708d)
    110 // -1.00560838484317760510577954846667125821113586425781250 ** 92252: 0x6e744b727536056b != 0x6e744b72753599a4 (0x6e744b72753599a4) (0x6e744b72753599a4)
    111 // 0.99999532655875444930870798998512327671051025390625000 ** 93511912: 0x1886c29a53ed9332 != 0x1886c29a53cba724 (0x1886c29a53cba724) (0x1886c29a53cba724)
    112 // -0.99989751779212987514711130643263459205627441406250000 ** -2864087: 0xda664b586d48712f != 0xda664b586d437e8c (0xda664b586d437e8c) (0xda664b586d437e8c)
    113 // -239.35307289280868303649185691028833389282226562500000000 ** -90: 0x137a8b43006c4438 != 0x137a8b43006c443e (0x137a8b43006c443e) (0x137a8b43006c443e)
    114 // 0.96128212369452570307259975379565730690956115722656250 ** -9670: 0x625d7eb275191f6f != 0x625d7eb2751920bf (0x625d7eb2751920c0) (0x625d7eb2751920bf)
    115 // 0.99996078564218904283222855156054720282554626464843750 ** 10583765: 0x1a829de67930f619 != 0x1a829de67951cc2d (0x1a829de67951cc2d) (0x1a829de67951cc2d)
    116 // -953.14032530394126752071315422654151916503906250000000000 ** 22: 0x4d8a6d863703112c != 0x4d8a6d863703112e (0x4d8a6d863703112e) (0x4d8a6d863703112e)
    117 // 0.99857985216514444370972114484175108373165130615234375 ** 335918: 0x14e345eb84f09d46 != 0x14e345eb84f036f4 (0x14e345eb84f036f4) (0x14e345eb84f036f4)
    118 // -1.20521595553711002857255607523256912827491760253906250 ** -2760: 0x117b0064dd165101 != 0x117b0064dd16511a (0x117b0064dd16511a) (0x117b0064dd16511a)
    119 // -1.19074911947068473594413262617308646440505981445312500 ** 3884: 0x7d132c80ed6973f6 != 0x7d132c80ed697072 (0x7d132c80ed697072) (0x7d132c80ed697072)
    120 // -0.99999908129426284819629699995857663452625274658203125 ** -172780371: 0xce400f20e4a13b1a != 0xce400f20e3e56454 (0xce400f20e3e56454) (0xce400f20e3e56454)
    121 // -0.00000000000000000000000000007930552628950037082519209 ** 8: 0x1142888ad3062fc1 != 0x1142888ad3062fbe (0x1142888ad3062fbe) (0x1142888ad3062fbe)
    122 // -0.99998583604065760521706351937609724700450897216796875 ** -5861784: 0x476b83d92617a928 != 0x476b83d9261b0d4e (0x476b83d9261b0d4e) (0x476b83d9261b0d4e)
    123 // 0.99989915564587761309667257592082023620605468750000000 ** 5468367: 0xe34d25f36eef64b != 0xe34d25f36f555ca (0xe34d25f36f555ca) (0xe34d25f36f555ca)
    124 // 0.99977805581863743444870351595454849302768707275390625 ** -130493: 0x428ba17ba9286df6 != 0x428ba17ba9282f94 (0x428ba17ba9282f94) (0x428ba17ba9282f94)
    125 // 29.19821057723854806909002945758402347564697265625000000 ** -20: 0x39d8ffec76e30251 != 0x39d8ffec76e3024a (0x39d8ffec76e3024a) (0x39d8ffec76e3024a)
    126 // 0.99985373283040668290766461723251268267631530761718750 ** 2345687: 0x20ff8c2fd8e5b4e0 != 0x20ff8c2fd8e00564 (0x20ff8c2fd8e00564) (0x20ff8c2fd8e00564)
    127 // -0.88383265987178571965188211834174580872058868408203125 ** -841: 0xc94c6878de27b17c != 0xc94c6878de27b20d (0xc94c6878de27b20d) (0xc94c6878de27b20d)
    128 // 0.99999589815682188298495702838408760726451873779296875 ** 72449292: 0x25233af2e809c6a6 != 0x25233af2e87ddc61 (0x25233af2e87ddc61) (0x25233af2e87ddc61)
    129 // 345736476.13618659973144531250000000000000000000000000000000000 ** -16: 0x2391db755176ac1b != 0x2391db755176ac19 (0x2391db755176ac19) (0x2391db755176ac19)
    130 // -0.99999307321818442506611290809814818203449249267578125 ** -55045397: 0xe250f3d69f25ec86 != 0xe250f3d69f03e875 (0xe250f3d69f03e875) (0xe250f3d69f03e875)
    131 // 1419676.56599932140670716762542724609375000000000000000000000 ** 25: 0x5fde72aa74287c2d != 0x5fde72aa74287c30 (0x5fde72aa74287c30) (0x5fde72aa74287c30)
    132 // 0.95797249286536323431562323094112798571586608886718750 ** -11483: 0x6c63b79e88c07b6f != 0x6c63b79e88c07a3f (0x6c63b79e88c07a3f) (0x6c63b79e88c07a3f)
    133 // 0.99998135132609855535434917328529991209506988525390625 ** 5682278: 0x3661650feb28b969 != 0x3661650feb22b7ed (0x3661650feb22b7ed) (0x3661650feb22b7ed)
    134 // -1.02020595459010832151136582979233935475349426269531250 ** -1668: 0x3ced0e90ddfec9a3 != 0x3ced0e90ddfecabc (0x3ced0e90ddfecabc) (0x3ced0e90ddfecabc)
    135 // 0.97281701550260646360612781791132874786853790283203125 ** 13717: 0x1dd88a88f24fc0d5 != 0x1dd88a88f24fb801 (0x1dd88a88f24fb801) (0x1dd88a88f24fb801)
    136 // -0.88724290003841266294415390802896581590175628662109375 ** -3437: 0xe502ab8ea591420d != 0xe502ab8ea5914139 (0xe502ab8ea5914139) (0xe502ab8ea5914139)
    137 // -0.99998630320599690701754980182158760726451873779296875 ** -11251995: 0xcdd44ff462cfbf32 != 0xcdd44ff462dbdcb2 (0xcdd44ff462dbdcb2) (0xcdd44ff462dbdcb2)
    138 // -0.99995743703658013235013868325040675699710845947265625 ** 13995099: 0x8a38604324e009d5 != 0x8a38604324c2ec7d (0x8a38604324c2ec7d) (0x8a38604324c2ec7d)
    139 // 0.99991090354494038816568490801728330552577972412109375 ** 7116340: 0x6c2ca56237c8161 != 0x6c2ca562366c00b (0x6c2ca562366c00b) (0x6c2ca562366c00b)
    140 // 0.00000022955540324908999561342678487341206761129797087 ** 27: 0x1ab703277bbb112d != 0x1ab703277bbb1131 (0x1ab703277bbb1130) (0x1ab703277bbb1131)
    141 // -1.00000041289256280663266807096078991889953613281250000 ** -365287834: 0x3255339a24caec8a != 0x3255339a26f00dc8 (0x3255339a26f00dc8) (0x3255339a26f00dc8)
    142 // -1.38949508997780957209045027411775663495063781738281250 ** 1996: 0x7b22ad71344bbd0b != 0x7b22ad71344bbddf (0x7b22ad71344bbddf) (0x7b22ad71344bbddf)
    143 // 0.99999867528282249118376512342365458607673645019531250 ** 164253172: 0x2c50f93fbc72a2b4 != 0x2c50f93fbb2d2fd4 (0x2c50f93fbb2d2fd4) (0x2c50f93fbb2d2fd4)
    144 // 1.00356688770562074708436739456374198198318481445312500 ** -141698: 0x12717fb35c5fd169 != 0x12717fb35c5ff8c8 (0x12717fb35c5ff8c8) (0x12717fb35c5ff8c8)
    145 // 368710687472107.18750000000000000000000000000000000000000000000000000 ** -20: 0x37282f0ae9be13c != 0x37282f0ae9be138 (0x37282f0ae9be138) (0x37282f0ae9be138)
    146 // 0.99246668780181890312519499275367707014083862304687500 ** -44617: 0x5e5ad2c000333e50 != 0x5e5ad2c0003351f5 (0x5e5ad2c0003351f5) (0x5e5ad2c0003351f5)
    147 // 1.13820783188362395499382273555966094136238098144531250 ** 1411: 0x506701df16f3a891 != 0x506701df16f3a70d (0x506701df16f3a70d) (0x506701df16f3a70d)
    148 // -0.99671841783028414241130121808964759111404418945312500 ** 97041: 0xa32c44e6e77f8d3b != 0xa32c44e6e77f6a7a (0xa32c44e6e77f6a7a) (0xa32c44e6e77f6a7a)
    149 // -0.57021831816264889614132016504299826920032501220703125 ** -802: 0x688ef2cc36fa60b3 != 0x688ef2cc36fa6064 (0x688ef2cc36fa6064) (0x688ef2cc36fa6064)
    150 // -0.97423450510790443601649712945800274610519409179687500 ** 23570: 0x874c760d601ec94 != 0x874c760d601e66f (0x874c760d601e66f) (0x874c760d601e66f)
    151 // -0.98067196425761504752216524138930253684520721435546875 ** -19882: 0x62ec606ceb9af0ae != 0x62ec606ceb9ae89c (0x62ec606ceb9ae89c) (0x62ec606ceb9ae89c)
    152 // 0.99683039770073134100414335989626124501228332519531250 ** -29823: 0x487816b919332b03 != 0x487816b919333fe4 (0x487816b919333fe4) (0x487816b919333fe4)
    153 // 0.99882797644578258378089685720624402165412902832031250 ** -540990: 0x792372efd5ca5ad2 != 0x792372efd5c92857 (0x792372efd5c92857) (0x792372efd5c92857)
    154 
    155 const testCases = [
    156  [0.99998738156596089776684266325901262462139129638671875 , 38583256],
    157  [-0.99843469603485224261874009243911132216453552246093750 , 326215],
    158  [0.00003722856305626354357250426541092735988058848306537 , -33],
    159  [-0.99996909838479330900895547529216855764389038085937500 , 17078527],
    160  [0.99992690642006631929206150743993930518627166748046875 , -6725291],
    161  [-0.99879181217764612110698863034485839307308197021484375 , 485128],
    162  [-1.00560838484317760510577954846667125821113586425781250 , 92252],
    163  [0.99999532655875444930870798998512327671051025390625000 , 93511912],
    164  [-0.99989751779212987514711130643263459205627441406250000 , -2864087],
    165  [-239.35307289280868303649185691028833389282226562500000000 , -90],
    166  [0.96128212369452570307259975379565730690956115722656250 , -9670],
    167  [0.99996078564218904283222855156054720282554626464843750 , 10583765],
    168  [-953.14032530394126752071315422654151916503906250000000000 , 22],
    169  [0.99857985216514444370972114484175108373165130615234375 , 335918],
    170  [-1.20521595553711002857255607523256912827491760253906250 , -2760],
    171  [-1.19074911947068473594413262617308646440505981445312500 , 3884],
    172  [-0.99999908129426284819629699995857663452625274658203125 , -172780371],
    173  [-0.00000000000000000000000000007930552628950037082519209 , 8],
    174  [-0.99998583604065760521706351937609724700450897216796875 , -5861784],
    175  [0.99989915564587761309667257592082023620605468750000000 , 5468367],
    176  [0.99977805581863743444870351595454849302768707275390625 , -130493],
    177  [29.19821057723854806909002945758402347564697265625000000 , -20],
    178  [0.99985373283040668290766461723251268267631530761718750 , 2345687],
    179  [-0.88383265987178571965188211834174580872058868408203125 , -841],
    180  [0.99999589815682188298495702838408760726451873779296875 , 72449292],
    181  [345736476.13618659973144531250000000000000000000000000000000000 , -16],
    182  [-0.99999307321818442506611290809814818203449249267578125 , -55045397],
    183  [1419676.56599932140670716762542724609375000000000000000000000 , 25],
    184  [0.95797249286536323431562323094112798571586608886718750 , -11483],
    185  [0.99998135132609855535434917328529991209506988525390625 , 5682278],
    186  [-1.02020595459010832151136582979233935475349426269531250 , -1668],
    187  [0.97281701550260646360612781791132874786853790283203125 , 13717],
    188  [-0.88724290003841266294415390802896581590175628662109375 , -3437],
    189  [-0.99998630320599690701754980182158760726451873779296875 , -11251995],
    190  [-0.99995743703658013235013868325040675699710845947265625 , 13995099],
    191  [0.99991090354494038816568490801728330552577972412109375 , 7116340],
    192  [0.00000022955540324908999561342678487341206761129797087 , 27],
    193  [-1.00000041289256280663266807096078991889953613281250000 , -365287834],
    194  [-1.38949508997780957209045027411775663495063781738281250 , 1996],
    195  [0.99999867528282249118376512342365458607673645019531250 , 164253172],
    196  [1.00356688770562074708436739456374198198318481445312500 , -141698],
    197  [368710687472107.18750000000000000000000000000000000000000000000000000 , -20],
    198  [0.99246668780181890312519499275367707014083862304687500 , -44617],
    199  [1.13820783188362395499382273555966094136238098144531250 , 1411],
    200  [-0.99671841783028414241130121808964759111404418945312500 , 97041],
    201  [-0.57021831816264889614132016504299826920032501220703125 , -802],
    202  [-0.97423450510790443601649712945800274610519409179687500 , 23570],
    203  [-0.98067196425761504752216524138930253684520721435546875 , -19882],
    204  [0.99683039770073134100414335989626124501228332519531250 , -29823],
    205  [0.99882797644578258378089685720624402165412902832031250 , -540990],
    206 ];
    207 
    208 // Test program modified to avoid bases with |abs(x) < 1| and large exponents.
    209 //
    210 // ```cpp
    211 // // Skip over likely denormals.
    212 // if (-1 < f && f < 0) {
    213 //   f -= 1;
    214 // } else if (0 < f && f < 1) {
    215 //   f += 1;
    216 // }
    217 //
    218 // // Keep the power small.
    219 // y &= 63;
    220 // ```
    221 //
    222 // 7.86990183266223297664510027971118688583374023437500000 ** 54: 0x49fa67548289784a != 0x49fa675482897851 (0x49fa675482897850) (0x49fa675482897851)
    223 // -1.00000018751738117828153917798772454261779785156250000 ** 25: 0xbff00004ea6921f6 != 0xbff00004ea6921fc (0xbff00004ea6921fc) (0xbff00004ea6921fc)
    224 // 1.19908234423429393977755808009533211588859558105468750 ** 58: 0x40e246fe7b30c6ec != 0x40e246fe7b30c6e6 (0x40e246fe7b30c6e6) (0x40e246fe7b30c6e6)
    225 // 1.00000649317438283780745678086532279849052429199218750 ** 42: 0x3ff0011dffabb95c != 0x3ff0011dffabb950 (0x3ff0011dffabb950) (0x3ff0011dffabb950)
    226 // 863370098.16819441318511962890625000000000000000000000000000000 ** 27: 0x7206b860614eb6df != 0x7206b860614eb6d9 (0x7206b860614eb6d9) (0x7206b860614eb6d9)
    227 // -1.00011928123711690830077714053913950920104980468750000 ** 57: 0xbff01bf129d0ffab != 0xbff01bf129d0ffbf (0xbff01bf129d0ffbf) (0xbff01bf129d0ffbf)
    228 // -1.14006037237328494704513559554470703005790710449218750 ** 30: 0x404983fd4d57c4aa != 0x404983fd4d57c4a0 (0x404983fd4d57c4a0) (0x404983fd4d57c4a0)
    229 // -447.11057737163486081044538877904415130615234375000000000 ** 8: 0x4455a4e4be220fce != 0x4455a4e4be220fd0 (0x4455a4e4be220fd0) (0x4455a4e4be220fd0)
    230 // -1.03656507831253685836259137431625276803970336914062500 ** 20: 0x4000681e0886d6db != 0x4000681e0886d6d9 (0x4000681e0886d6d9) (0x4000681e0886d6d9)
    231 // -1.00000465330344945336094042431795969605445861816406250 ** 41: 0xbff000c81257efc1 != 0xbff000c81257efc6 (0xbff000c81257efc6) (0xbff000c81257efc6)
    232 // -1.00002726631492944164847358479164540767669677734375000 ** 14: 0x3ff00190579a2f93 != 0x3ff00190579a2f90 (0x3ff00190579a2f90) (0x3ff00190579a2f90)
    233 // 2512068.57641875604167580604553222656250000000000000000000000 ** 26: 0x627b50512391a46e != 0x627b50512391a46c (0x627b50512391a46c) (0x627b50512391a46c)
    234 // 3309586784.85019683837890625000000000000000000000000000000000000 ** 30: 0x7b3a5b69a3a40717 != 0x7b3a5b69a3a40719 (0x7b3a5b69a3a40719) (0x7b3a5b69a3a40719)
    235 // 1.40742719307547781149025922786677256226539611816406250 ** 19: 0x4084a6ad66b5f1ce != 0x4084a6ad66b5f1d1 (0x4084a6ad66b5f1d0) (0x4084a6ad66b5f1d1)
    236 // 1.00035740860596344958821646287105977535247802734375000 ** 36: 0x3ff0350873b3189e != 0x3ff0350873b318a0 (0x3ff0350873b318a0) (0x3ff0350873b318a0)
    237 testCases.push(
    238  [7.86990183266223297664510027971118688583374023437500000 , 54],
    239  [-1.00000018751738117828153917798772454261779785156250000 , 25],
    240  [1.19908234423429393977755808009533211588859558105468750 , 58],
    241  [1.00000649317438283780745678086532279849052429199218750 , 42],
    242  [863370098.16819441318511962890625000000000000000000000000000000 , 27],
    243  [-1.00011928123711690830077714053913950920104980468750000 , 57],
    244  [-1.14006037237328494704513559554470703005790710449218750 , 30],
    245  [-447.11057737163486081044538877904415130615234375000000000 , 8],
    246  [-1.03656507831253685836259137431625276803970336914062500 , 20],
    247  [-1.00000465330344945336094042431795969605445861816406250 , 41],
    248  [-1.00002726631492944164847358479164540767669677734375000 , 14],
    249  [2512068.57641875604167580604553222656250000000000000000000000 , 26],
    250  [3309586784.85019683837890625000000000000000000000000000000000000 , 30],
    251  [1.40742719307547781149025922786677256226539611816406250 , 19],
    252  [1.00035740860596344958821646287105977535247802734375000 , 36],
    253 );
    254 
    255 // Test program modified to only use small integer bases (< 20) and positive exponents.
    256 //
    257 // ```cpp
    258 // f = static_cast<double>(x);
    259 // f = std::fmod(f, 20);
    260 // y &= 63;
    261 // ```
    262 //
    263 // 13.00000000000000000000000000000000000000000000000000000 ** 31: 0x471a3d23b248d522 != 0x471a3d23b248d520 (0x471a3d23b248d520) (0x471a3d23b248d520)
    264 // 13.00000000000000000000000000000000000000000000000000000 ** 41: 0x496a51a4d0054bb2 != 0x496a51a4d0054bb1 (0x496a51a4d0054bb0) (0x496a51a4d0054bb1)
    265 // 13.00000000000000000000000000000000000000000000000000000 ** 51: 0x4bba6635f3af40fa != 0x4bba6635f3af40f8 (0x4bba6635f3af40f8) (0x4bba6635f3af40f8)
    266 // 13.00000000000000000000000000000000000000000000000000000 ** 58: 0x4d58af19e7576d60 != 0x4d58af19e7576d5e (0x4d58af19e7576d5e) (0x4d58af19e7576d5e)
    267 // 13.00000000000000000000000000000000000000000000000000000 ** 63: 0x4e817b180a97c789 != 0x4e817b180a97c787 (0x4e817b180a97c787) (0x4e817b180a97c787)
    268 // 11.00000000000000000000000000000000000000000000000000000 ** 63: 0x4d8ec9288a0088ce != 0x4d8ec9288a0088d0 (0x4d8ec9288a0088d0) (0x4d8ec9288a0088d0)
    269 // 13.00000000000000000000000000000000000000000000000000000 ** 47: 0x4ace49afd4c20163 != 0x4ace49afd4c20161 (0x4ace49afd4c20161) (0x4ace49afd4c20161)
    270 // 13.00000000000000000000000000000000000000000000000000000 ** 41: 0x496a51a4d0054bb2 != 0x496a51a4d0054bb1 (0x496a51a4d0054bb0) (0x496a51a4d0054bb1)
    271 // 13.00000000000000000000000000000000000000000000000000000 ** 63: 0x4e817b180a97c789 != 0x4e817b180a97c787 (0x4e817b180a97c787) (0x4e817b180a97c787)
    272 // 13.00000000000000000000000000000000000000000000000000000 ** 31: 0x471a3d23b248d522 != 0x471a3d23b248d520 (0x471a3d23b248d520) (0x471a3d23b248d520)
    273 // 13.00000000000000000000000000000000000000000000000000000 ** 49: 0x4b43fea5137412eb != 0x4b43fea5137412e9 (0x4b43fea5137412e9) (0x4b43fea5137412e9)
    274 // 13.00000000000000000000000000000000000000000000000000000 ** 58: 0x4d58af19e7576d60 != 0x4d58af19e7576d5e (0x4d58af19e7576d5e) (0x4d58af19e7576d5e)
    275 // 13.00000000000000000000000000000000000000000000000000000 ** 31: 0x471a3d23b248d522 != 0x471a3d23b248d520 (0x471a3d23b248d520) (0x471a3d23b248d520)
    276 // 11.00000000000000000000000000000000000000000000000000000 ** 63: 0x4d8ec9288a0088ce != 0x4d8ec9288a0088d0 (0x4d8ec9288a0088d0) (0x4d8ec9288a0088d0)
    277 // 13.00000000000000000000000000000000000000000000000000000 ** 31: 0x471a3d23b248d522 != 0x471a3d23b248d520 (0x471a3d23b248d520) (0x471a3d23b248d520)
    278 testCases.push(
    279  [13.00000000000000000000000000000000000000000000000000000 , 31],
    280  [13.00000000000000000000000000000000000000000000000000000 , 41],
    281  [13.00000000000000000000000000000000000000000000000000000 , 51],
    282  [13.00000000000000000000000000000000000000000000000000000 , 58],
    283  [13.00000000000000000000000000000000000000000000000000000 , 63],
    284  [11.00000000000000000000000000000000000000000000000000000 , 63],
    285  [13.00000000000000000000000000000000000000000000000000000 , 47],
    286  [13.00000000000000000000000000000000000000000000000000000 , 41],
    287  [13.00000000000000000000000000000000000000000000000000000 , 63],
    288  [13.00000000000000000000000000000000000000000000000000000 , 31],
    289  [13.00000000000000000000000000000000000000000000000000000 , 49],
    290  [13.00000000000000000000000000000000000000000000000000000 , 58],
    291  [13.00000000000000000000000000000000000000000000000000000 , 31],
    292  [11.00000000000000000000000000000000000000000000000000000 , 63],
    293  [13.00000000000000000000000000000000000000000000000000000 , 31],
    294 );
    295 
    296 // Test program modified to only use small integer bases (< 20) and negative exponents.
    297 //
    298 // ```cpp
    299 // f = static_cast<double>(x);
    300 // f = std::fmod(f, 20);
    301 // y &= 63;
    302 // y = -y;
    303 // ```
    304 //
    305 // 14.00000000000000000000000000000000000000000000000000000 ** -57: 0x325f938745f05e58 != 0x325f938745f05e5a (0x325f938745f05e5a) (0x325f938745f05e5a)
    306 // 11.00000000000000000000000000000000000000000000000000000 ** -53: 0x34791bddc7b3025a != 0x34791bddc7b30259 (0x34791bddc7b30258) (0x34791bddc7b30259)
    307 // 7.00000000000000000000000000000000000000000000000000000 ** -57: 0x35ef938745f05e58 != 0x35ef938745f05e5a (0x35ef938745f05e5a) (0x35ef938745f05e5a)
    308 // 15.00000000000000000000000000000000000000000000000000000 ** -50: 0x33b933babb6d9cd8 != 0x33b933babb6d9cda (0x33b933babb6d9cda) (0x33b933babb6d9cda)
    309 // 14.00000000000000000000000000000000000000000000000000000 ** -57: 0x325f938745f05e58 != 0x325f938745f05e5a (0x325f938745f05e5a) (0x325f938745f05e5a)
    310 // 13.00000000000000000000000000000000000000000000000000000 ** -33: 0x384d8ee9f0edfd7c != 0x384d8ee9f0edfd7d (0x384d8ee9f0edfd7e) (0x384d8ee9f0edfd7d)
    311 // 19.00000000000000000000000000000000000000000000000000000 ** -53: 0x31dd0994e8aaf4e0 != 0x31dd0994e8aaf4e1 (0x31dd0994e8aaf4e2) (0x31dd0994e8aaf4e1)
    312 // 15.00000000000000000000000000000000000000000000000000000 ** -50: 0x33b933babb6d9cd8 != 0x33b933babb6d9cda (0x33b933babb6d9cda) (0x33b933babb6d9cda)
    313 // 14.00000000000000000000000000000000000000000000000000000 ** -57: 0x325f938745f05e58 != 0x325f938745f05e5a (0x325f938745f05e5a) (0x325f938745f05e5a)
    314 // 13.00000000000000000000000000000000000000000000000000000 ** -63: 0x315d4a0a2c8d4bd8 != 0x315d4a0a2c8d4bdb (0x315d4a0a2c8d4bdb) (0x315d4a0a2c8d4bdb)
    315 // 11.00000000000000000000000000000000000000000000000000000 ** -53: 0x34791bddc7b3025a != 0x34791bddc7b30259 (0x34791bddc7b30258) (0x34791bddc7b30259)
    316 // 15.00000000000000000000000000000000000000000000000000000 ** -50: 0x33b933babb6d9cd8 != 0x33b933babb6d9cda (0x33b933babb6d9cda) (0x33b933babb6d9cda)
    317 // 13.00000000000000000000000000000000000000000000000000000 ** -53: 0x33ad60ed868e2926 != 0x33ad60ed868e2928 (0x33ad60ed868e2928) (0x33ad60ed868e2928)
    318 // 19.00000000000000000000000000000000000000000000000000000 ** -53: 0x31dd0994e8aaf4e0 != 0x31dd0994e8aaf4e1 (0x31dd0994e8aaf4e2) (0x31dd0994e8aaf4e1)
    319 // 13.00000000000000000000000000000000000000000000000000000 ** -33: 0x384d8ee9f0edfd7c != 0x384d8ee9f0edfd7d (0x384d8ee9f0edfd7e) (0x384d8ee9f0edfd7d)
    320 testCases.push(
    321  [14.00000000000000000000000000000000000000000000000000000 , -57],
    322  [11.00000000000000000000000000000000000000000000000000000 , -53],
    323  [7.00000000000000000000000000000000000000000000000000000 , -57],
    324  [15.00000000000000000000000000000000000000000000000000000 , -50],
    325  [14.00000000000000000000000000000000000000000000000000000 , -57],
    326  [13.00000000000000000000000000000000000000000000000000000 , -33],
    327  [19.00000000000000000000000000000000000000000000000000000 , -53],
    328  [15.00000000000000000000000000000000000000000000000000000 , -50],
    329  [14.00000000000000000000000000000000000000000000000000000 , -57],
    330  [13.00000000000000000000000000000000000000000000000000000 , -63],
    331  [11.00000000000000000000000000000000000000000000000000000 , -53],
    332  [15.00000000000000000000000000000000000000000000000000000 , -50],
    333  [13.00000000000000000000000000000000000000000000000000000 , -53],
    334  [19.00000000000000000000000000000000000000000000000000000 , -53],
    335  [13.00000000000000000000000000000000000000000000000000000 , -33],
    336 );
    337 
    338 // std::pow is less precise on Windows.
    339 const maxError = getBuildConfiguration("windows") ? 3 : 1;
    340 
    341 // Ensure the error is less-or-equal to |maxError| ULP when compared to fdlibm.
    342 for (let [x, y] of testCases) {
    343  let actual = Math.pow(x, y);
    344  let expected = fdlibm.pow(x, y);
    345  let error = errorInULP(actual, expected);
    346 
    347  assertEq(error <= maxError, true,
    348           `${x} ** ${y}: ${actual} (${toBits(actual).toString(16)}) != ${expected} (${toBits(expected).toString(16)})`);
    349 }
    350 
    351 // Test program modified to use 4 as the exponent:
    352 //
    353 // ```cpp
    354 // y = 4;
    355 // ```
    356 //
    357 // -0.00000000000000000000000000000749666789562697097993956 ** 4: 0x27bfdbe3cf0b7e1d != 0x27bfdbe3cf0b7e1b (0x27bfdbe3cf0b7e1b) (0x27bfdbe3cf0b7e1b)
    358 // 0.00000000000000000000000000000000000000000000000000000 ** 4: 0xd3e1e77bd0d8f5d != 0xd3e1e77bd0d8f5f (0xd3e1e77bd0d8f5f) (0xd3e1e77bd0d8f5f)
    359 // -0.00000000000000000000000000023705601542216470968966009 ** 4: 0x28fe60d2f5131d02 != 0x28fe60d2f5131d04 (0x28fe60d2f5131d04) (0x28fe60d2f5131d04)
    360 // 0.00000000000000000000000000000000000000000000000000441 ** 4: 0x161dad0fa681c66c != 0x161dad0fa681c66b (0x161dad0fa681c66a) (0x161dad0fa681c66b)
    361 // 0.00000000000000537255761599995092558925668894011631095 ** 4: 0x3414eb4baea214b6 != 0x3414eb4baea214b5 (0x3414eb4baea214b4) (0x3414eb4baea214b5)
    362 // 0.01225688384384779339164595057809492573142051696777344 ** 4: 0x3e583bd550871dfc != 0x3e583bd550871dfd (0x3e583bd550871dfe) (0x3e583bd550871dfd)
    363 // -0.00000000000000000000000000000000000000000000000000000 ** 4: 0xa59292360f6d326 != 0xa59292360f6d324 (0xa59292360f6d324) (0xa59292360f6d324)
    364 // -0.00000000000000000000000000000000000000000000000000000 ** 4: 0x109fb7a8459811ec != 0x109fb7a8459811ed (0x109fb7a8459811ee) (0x109fb7a8459811ed)
    365 // -120834175976112453093144522854609799898808186321228136949237230085114691584.00000000000000000000000000000000000000000000000000000 ** 4: 0x7d74dcc37a2d7dc2 != 0x7d74dcc37a2d7dc3 (0x7d74dcc37a2d7dc4) (0x7d74dcc37a2d7dc3)
    366 // -6676.83140968165753292851150035858154296875000000000000000 ** 4: 0x431c3e0ef48fe66a != 0x431c3e0ef48fe66c (0x431c3e0ef48fe66c) (0x431c3e0ef48fe66c)
    367 // -0.00000000000000000000000000000000000000000000039753861 ** 4: 0x1a3a87f39f288766 != 0x1a3a87f39f288764 (0x1a3a87f39f288764) (0x1a3a87f39f288764)
    368 // 129749516186492032220917661696.00000000000000000000000000000000000000000000000000000 ** 4: 0x581cc58a512bdd10 != 0x581cc58a512bdd12 (0x581cc58a512bdd12) (0x581cc58a512bdd12)
    369 // -1888635225450734959219733085647207705818299180319259746124169216.00000000000000000000000000000000000000000000000000000 ** 4: 0x747bc423aba49de6 != 0x747bc423aba49de5 (0x747bc423aba49de4) (0x747bc423aba49de5)
    370 // 7934926680560039158281691725824.00000000000000000000000000000000000000000000000000000 ** 4: 0x5997fceb5eed5c94 != 0x5997fceb5eed5c93 (0x5997fceb5eed5c92) (0x5997fceb5eed5c93)
    371 // -0.00000000000000579868166379701264244398310517312073637 ** 4: 0x341c635a1a764ef2 != 0x341c635a1a764ef0 (0x341c635a1a764ef0) (0x341c635a1a764ef0)
    372 //
    373 //
    374 // Test program modified to avoid bases with |abs(x) < 1| and large exponents.
    375 //
    376 // ```cpp
    377 // // Skip over likely denormals.
    378 // if (-1 < f && f < 0) {
    379 //   f -= 1;
    380 // } else if (0 < f && f < 1) {
    381 //   f += 1;
    382 // }
    383 //
    384 // f = std::fmod(f, 20);
    385 //
    386 // y = 4;
    387 // ```
    388 //
    389 // 4.73347349464893341064453125000000000000000000000000000 ** 4: 0x407f604c239c2323 != 0x407f604c239c2321 (0x407f604c239c2321) (0x407f604c239c2321)
    390 // -12.35635152040049433708190917968750000000000000000000000 ** 4: 0x40d6c3c0652f0948 != 0x40d6c3c0652f0949 (0x40d6c3c0652f094a) (0x40d6c3c0652f0949)
    391 // -1.50385549572482823954544528533006086945533752441406250 ** 4: 0x40147581145bc6e6 != 0x40147581145bc6e7 (0x40147581145bc6e8) (0x40147581145bc6e7)
    392 // -8.93048901623114943504333496093750000000000000000000000 ** 4: 0x40b8d8a463c28bd6 != 0x40b8d8a463c28bd7 (0x40b8d8a463c28bd8) (0x40b8d8a463c28bd7)
    393 // 19.02711385915608843788504600524902343750000000000000000 ** 4: 0x40ffffa7d5df2562 != 0x40ffffa7d5df2560 (0x40ffffa7d5df2560) (0x40ffffa7d5df2560)
    394 // 17.83878016096969076897948980331420898437500000000000000 ** 4: 0x40f8b914a6acb498 != 0x40f8b914a6acb497 (0x40f8b914a6acb496) (0x40f8b914a6acb497)
    395 // 12.90541613101959228515625000000000000000000000000000000 ** 4: 0x40db16b4c2dafa0a != 0x40db16b4c2dafa0c (0x40db16b4c2dafa0c) (0x40db16b4c2dafa0c)
    396 // -18.34655402903445065021514892578125000000000000000000000 ** 4: 0x40fba90e5b7bbc6a != 0x40fba90e5b7bbc6b (0x40fba90e5b7bbc6c) (0x40fba90e5b7bbc6b)
    397 // -13.28634420270100235939025878906250000000000000000000000 ** 4: 0x40de6e70b9ed821a != 0x40de6e70b9ed821c (0x40de6e70b9ed821c) (0x40de6e70b9ed821c)
    398 // 18.52965961024165153503417968750000000000000000000000000 ** 4: 0x40fcc800b850b01a != 0x40fcc800b850b018 (0x40fcc800b850b018) (0x40fcc800b850b018)
    399 // 13.32226210648514097556471824645996093750000000000000000 ** 4: 0x40dec3063a559350 != 0x40dec3063a55934e (0x40dec3063a55934e) (0x40dec3063a55934e)
    400 // 1.09174693829848346027233674249146133661270141601562500 ** 4: 0x3ff6bafe5bbe7532 != 0x3ff6bafe5bbe7533 (0x3ff6bafe5bbe7534) (0x3ff6bafe5bbe7533)
    401 // 9.35059530444141273619607090950012207031250000000000000 ** 4: 0x40bddca3dd9f5c8f != 0x40bddca3dd9f5c91 (0x40bddca3dd9f5c91) (0x40bddca3dd9f5c91)
    402 // 17.59552449546754360198974609375000000000000000000000000 ** 4: 0x40f766db2706f434 != 0x40f766db2706f435 (0x40f766db2706f436) (0x40f766db2706f435)
    403 // 17.94561576098203659057617187500000000000000000000000000 ** 4: 0x40f952110041965c != 0x40f952110041965a (0x40f952110041965a) (0x40f952110041965a)
    404 const testCases4 = [
    405  [-0.00000000000000000000000000000749666789562697097993956 , 4],
    406  [0.00000000000000000000000000000000000000000000000000000 , 4],
    407  [-0.00000000000000000000000000023705601542216470968966009 , 4],
    408  [0.00000000000000000000000000000000000000000000000000441 , 4],
    409  [0.00000000000000537255761599995092558925668894011631095 , 4],
    410  [0.01225688384384779339164595057809492573142051696777344 , 4],
    411  [-0.00000000000000000000000000000000000000000000000000000 , 4],
    412  [-0.00000000000000000000000000000000000000000000000000000 , 4],
    413  [-120834175976112453093144522854609799898808186321228136949237230085114691584.00000000000000000000000000000000000000000000000000000 , 4],
    414  [-6676.83140968165753292851150035858154296875000000000000000 , 4],
    415  [-0.00000000000000000000000000000000000000000000039753861 , 4],
    416  [129749516186492032220917661696.00000000000000000000000000000000000000000000000000000 , 4],
    417  [-1888635225450734959219733085647207705818299180319259746124169216.00000000000000000000000000000000000000000000000000000 , 4],
    418  [7934926680560039158281691725824.00000000000000000000000000000000000000000000000000000 , 4],
    419  [-0.00000000000000579868166379701264244398310517312073637 , 4],
    420 
    421  [4.73347349464893341064453125000000000000000000000000000 , 4],
    422  [-12.35635152040049433708190917968750000000000000000000000 , 4],
    423  [-1.50385549572482823954544528533006086945533752441406250 , 4],
    424  [-8.93048901623114943504333496093750000000000000000000000 , 4],
    425  [19.02711385915608843788504600524902343750000000000000000 , 4],
    426  [17.83878016096969076897948980331420898437500000000000000 , 4],
    427  [12.90541613101959228515625000000000000000000000000000000 , 4],
    428  [-18.34655402903445065021514892578125000000000000000000000 , 4],
    429  [-13.28634420270100235939025878906250000000000000000000000 , 4],
    430  [18.52965961024165153503417968750000000000000000000000000 , 4],
    431  [13.32226210648514097556471824645996093750000000000000000 , 4],
    432  [1.09174693829848346027233674249146133661270141601562500 , 4],
    433  [9.35059530444141273619607090950012207031250000000000000 , 4],
    434  [17.59552449546754360198974609375000000000000000000000000 , 4],
    435  [17.94561576098203659057617187500000000000000000000000000 , 4],
    436 ];
    437 
    438 // Ensure the error is less-or-equal to 2 ULP when compared to fdlibm.
    439 //
    440 // This can produce a larger error than std::pow, because we evaluate
    441 // |x ** 4| as |(x * x) * (x * x)| to match Ion.
    442 for (let [x, y] of testCases4) {
    443  let actual = Math.pow(x, y);
    444  let expected = fdlibm.pow(x, y);
    445  let error = errorInULP(actual, expected);
    446  assertEq(error <= 2, true,
    447           `${x} ** ${y}: ${actual} (${toBits(actual).toString(16)}) != ${expected} (${toBits(expected).toString(16)})`);
    448 }
    449 
    450 for (let [x, y] of testCases4) {
    451  // Replace |y| with a constant to trigger Ion optimisations.
    452  let actual = Math.pow(x, 4);
    453  let expected = fdlibm.pow(x, y);
    454  let error = errorInULP(actual, expected);
    455  assertEq(error <= 2, true,
    456           `${x} ** ${y}: ${actual} (${toBits(actual).toString(16)}) != ${expected} (${toBits(expected).toString(16)})`);
    457 }
    458 
    459 // Test program modified to use 3 as the exponent:
    460 //
    461 // ```cpp
    462 // y = 3;
    463 // ```
    464 //
    465 // 196194373276.42089843750000000000000000000000000000000000000000000 ** 3: 0x46f745720bc58e22 != 0x46f745720bc58e23 (0x46f745720bc58e24) (0x46f745720bc58e23)
    466 // 17260025115986696435331651385474892363490876322742272.00000000000000000000000000000000000000000000000000000 ** 3: 0x6077f8040eb542fc != 0x6077f8040eb542fb (0x6077f8040eb542fa) (0x6077f8040eb542fb)
    467 // -0.00000000000000000000000000000000000000000000000000000 ** 3: 0x9307c17ddf2c4af6 != 0x9307c17ddf2c4af7 (0x9307c17ddf2c4af8) (0x9307c17ddf2c4af7)
    468 // 2359506498398344427475761591701240715936602989985583832867274752.00000000000000000000000000000000000000000000000000000 ** 3: 0x6767960b1076dc24 != 0x6767960b1076dc25 (0x6767960b1076dc26) (0x6767960b1076dc25)
    469 // 22724457948673043906745552566513068013978508710758109286797554897659283949989408425377792.00000000000000000000000000000000000000000000000000000 ** 3: 0x76f74ab82115b372 != 0x76f74ab82115b373 (0x76f74ab82115b374) (0x76f74ab82115b373)
    470 // -1024872849611580448634200763411882795753013248.00000000000000000000000000000000000000000000000000000 ** 3: 0xdbf7b2694dce1d6c != 0xdbf7b2694dce1d6b (0xdbf7b2694dce1d6a) (0xdbf7b2694dce1d6b)
    471 // -918435268181356203923125447950336.00000000000000000000000000000000000000000000000000000 ** 3: 0xd476ab3173dbfcc0 != 0xd476ab3173dbfcbf (0xd476ab3173dbfcbe) (0xd476ab3173dbfcbf)
    472 // 558545783776545344834655968246618719333738303286453207040.00000000000000000000000000000000000000000000000000000 ** 3: 0x634716045b3ee61c != 0x634716045b3ee61b (0x634716045b3ee61a) (0x634716045b3ee61b)
    473 // 0.00000000000000000000000000000000000000000000000000000 ** 3: 0x1c6f3bddc90315c != 0x1c6f3bddc90315b (0x1c6f3bddc90315a) (0x1c6f3bddc90315b)
    474 // -0.00000000000261062225071774409619236799548496917242058 ** 3: 0xb8b7a667f8b6344e != 0xb8b7a667f8b6344f (0xb8b7a667f8b63450) (0xb8b7a667f8b6344f)
    475 // 0.00000000000000000000000000000000000000000000012475377 ** 3: 0x23571f25316bb01e != 0x23571f25316bb01f (0x23571f25316bb020) (0x23571f25316bb01f)
    476 // -0.00000000000000000000000000000000000000000000000000000 ** 3: 0x93f6c04c12acc76c != 0x93f6c04c12acc76d (0x93f6c04c12acc76e) (0x93f6c04c12acc76d)
    477 // 0.00000000000000000000000000000000000000000000000000000 ** 3: 0x676eb3aa0a63236 != 0x676eb3aa0a63237 (0x676eb3aa0a63238) (0x676eb3aa0a63237)
    478 // 0.00000000000000000000000007454937961610833261396029146 ** 3: 0x3047fcbe59481112 != 0x3047fcbe59481111 (0x3047fcbe59481110) (0x3047fcbe59481111)
    479 // 0.00000000000000000000000000000000000003326770580987513 ** 3: 0x2896aaec8bb845c8 != 0x2896aaec8bb845c9 (0x2896aaec8bb845ca) (0x2896aaec8bb845c9)
    480 //
    481 //
    482 // Test program modified to avoid bases with |abs(x) < 1| and large exponents.
    483 //
    484 // ```cpp
    485 // // Skip over likely denormals.
    486 // if (-1 < f && f < 0) {
    487 //   f -= 1;
    488 // } else if (0 < f && f < 1) {
    489 //   f += 1;
    490 // }
    491 //
    492 // f = std::fmod(f, 20);
    493 //
    494 // y = 3;
    495 // ```
    496 //
    497 // -11.40858423709869384765625000000000000000000000000000000 ** 3: 0xc0973392c88cadcc != 0xc0973392c88cadcd (0xc0973392c88cadce) (0xc0973392c88cadcd)
    498 // 11.42477834224700927734375000000000000000000000000000000 ** 3: 0x40974ce701d58518 != 0x40974ce701d58519 (0x40974ce701d5851a) (0x40974ce701d58519)
    499 // -11.46123231985238533070514677092432975769042968750000000 ** 3: 0xc097862ed0211e58 != 0xc097862ed0211e59 (0xc097862ed0211e5a) (0xc097862ed0211e59)
    500 // -11.40183842182159423828125000000000000000000000000000000 ** 3: 0xc097290b23fe8cdc != 0xc097290b23fe8cdd (0xc097290b23fe8cde) (0xc097290b23fe8cdd)
    501 // 2.87109172078278795936512324260547757148742675781250000 ** 3: 0x4037aab95517cdd0 != 0x4037aab95517cdcf (0x4037aab95517cdce) (0x4037aab95517cdcf)
    502 // -0.72109144181013107299804687500000000000000000000000000 ** 3: 0xbfd7ff25d4fd46bc != 0xbfd7ff25d4fd46bd (0xbfd7ff25d4fd46be) (0xbfd7ff25d4fd46bd)
    503 // 5.70116788148880004882812500000000000000000000000000000 ** 3: 0x406729d1c53687b4 != 0x406729d1c53687b5 (0x406729d1c53687b6) (0x406729d1c53687b5)
    504 // -11.32285048566092200417187996208667755126953125000000000 ** 3: 0xc096aeac14d25c0e != 0xc096aeac14d25c0f (0xc096aeac14d25c10) (0xc096aeac14d25c0f)
    505 // 1.41961999237537384033203125000000000000000000000000000 ** 3: 0x4006e34ea8957732 != 0x4006e34ea8957733 (0x4006e34ea8957734) (0x4006e34ea8957733)
    506 // -11.52091628707762538397219032049179077148437500000000000 ** 3: 0xc097e4c12ab5e96e != 0xc097e4c12ab5e96f (0xc097e4c12ab5e970) (0xc097e4c12ab5e96f)
    507 // -5.73415940999984741210937500000000000000000000000000000 ** 3: 0xc067915c3febbeba != 0xc067915c3febbebb (0xc067915c3febbebc) (0xc067915c3febbebb)
    508 // 1.41478560105390638312883311300538480281829833984375000 ** 3: 0x4006a7a69b402738 != 0x4006a7a69b402737 (0x4006a7a69b402736) (0x4006a7a69b402737)
    509 // -2.88328036665916442871093750000000000000000000000000000 ** 3: 0xc037f8371e1d17ce != 0xc037f8371e1d17cf (0xc037f8371e1d17d0) (0xc037f8371e1d17cf)
    510 // 1.42408178602072932328326260176254436373710632324218750 ** 3: 0x40071aba43b3bcea != 0x40071aba43b3bceb (0x40071aba43b3bcec) (0x40071aba43b3bceb)
    511 // 11.48128501093015074729919433593750000000000000000000000 ** 3: 0x4097a5d8fdac3954 != 0x4097a5d8fdac3955 (0x4097a5d8fdac3956) (0x4097a5d8fdac3955)
    512 const testCases3 = [
    513  [196194373276.42089843750000000000000000000000000000000000000000000 , 3],
    514  [17260025115986696435331651385474892363490876322742272.00000000000000000000000000000000000000000000000000000 , 3],
    515  [-0.00000000000000000000000000000000000000000000000000000 , 3],
    516  [2359506498398344427475761591701240715936602989985583832867274752.00000000000000000000000000000000000000000000000000000 , 3],
    517  [22724457948673043906745552566513068013978508710758109286797554897659283949989408425377792.00000000000000000000000000000000000000000000000000000 , 3],
    518  [-1024872849611580448634200763411882795753013248.00000000000000000000000000000000000000000000000000000 , 3],
    519  [-918435268181356203923125447950336.00000000000000000000000000000000000000000000000000000 , 3],
    520  [558545783776545344834655968246618719333738303286453207040.00000000000000000000000000000000000000000000000000000 , 3],
    521  [0.00000000000000000000000000000000000000000000000000000 , 3],
    522  [-0.00000000000261062225071774409619236799548496917242058 , 3],
    523  [0.00000000000000000000000000000000000000000000012475377 , 3],
    524  [-0.00000000000000000000000000000000000000000000000000000 , 3],
    525  [0.00000000000000000000000000000000000000000000000000000 , 3],
    526  [0.00000000000000000000000007454937961610833261396029146 , 3],
    527  [0.00000000000000000000000000000000000003326770580987513 , 3],
    528 
    529  [-11.40858423709869384765625000000000000000000000000000000 , 3],
    530  [11.42477834224700927734375000000000000000000000000000000 , 3],
    531  [-11.46123231985238533070514677092432975769042968750000000 , 3],
    532  [-11.40183842182159423828125000000000000000000000000000000 , 3],
    533  [2.87109172078278795936512324260547757148742675781250000 , 3],
    534  [-0.72109144181013107299804687500000000000000000000000000 , 3],
    535  [5.70116788148880004882812500000000000000000000000000000 , 3],
    536  [-11.32285048566092200417187996208667755126953125000000000 , 3],
    537  [1.41961999237537384033203125000000000000000000000000000 , 3],
    538  [-11.52091628707762538397219032049179077148437500000000000 , 3],
    539  [-5.73415940999984741210937500000000000000000000000000000 , 3],
    540  [1.41478560105390638312883311300538480281829833984375000 , 3],
    541  [-2.88328036665916442871093750000000000000000000000000000 , 3],
    542  [1.42408178602072932328326260176254436373710632324218750 , 3],
    543  [11.48128501093015074729919433593750000000000000000000000 , 3],
    544 ];
    545 
    546 // Ensure the error is less-or-equal to 2 ULP when compared to fdlibm.
    547 //
    548 // This can produce a larger error than std::pow, because we evaluate
    549 // |x ** 3| as |(x * x) * x| to match Ion.
    550 for (let [x, y] of testCases3) {
    551  let actual = Math.pow(x, y);
    552  let expected = fdlibm.pow(x, y);
    553  let error = errorInULP(actual, expected);
    554  assertEq(error <= 2, true,
    555           `${x} ** ${y}: ${actual} (${toBits(actual).toString(16)}) != ${expected} (${toBits(expected).toString(16)})`);
    556 }
    557 
    558 for (let [x, y] of testCases3) {
    559  // Replace |y| with a constant to trigger Ion optimisations.
    560  let actual = Math.pow(x, 3);
    561  let expected = fdlibm.pow(x, y);
    562  let error = errorInULP(actual, expected);
    563  assertEq(error <= 2, true,
    564           `${x} ** ${y}: ${actual} (${toBits(actual).toString(16)}) != ${expected} (${toBits(expected).toString(16)})`);
    565 }
    566 
    567 if (typeof reportCompare === "function")
    568  reportCompare(true, true);