tor-browser

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

testFractionToDouble.cpp (7143B)


      1 /* This Source Code Form is subject to the terms of the Mozilla Public
      2 * License, v. 2.0. If a copy of the MPL was not distributed with this
      3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      4 
      5 #ifdef JS_HAS_INTL_API
      6 
      7 #  include <cmath>
      8 #  include <stdint.h>
      9 
     10 #  include "builtin/temporal/Temporal.h"
     11 #  include "jsapi-tests/tests.h"
     12 #  include "vm/Int128.h"
     13 
     14 using namespace js;
     15 using namespace js::temporal;
     16 
     17 // Simple test using numerators and denominators where the result can be
     18 // computed through standard double division.
     19 BEGIN_TEST(testFraction_simple) {
     20  int64_t numerators[] = {
     21      0, 1, 2, 10, 100, INT32_MIN, INT32_MAX,
     22  };
     23 
     24  int64_t denominators[] = {
     25      1, 2, 3, 10, 100, 1000,
     26  };
     27 
     28  for (auto numerator : numerators) {
     29    for (auto denominator : denominators) {
     30      double result = double(numerator) / double(denominator);
     31 
     32      CHECK_EQUAL(FractionToDouble(numerator, denominator), result);
     33      CHECK_EQUAL(FractionToDouble(Int128{numerator}, Int128{denominator}),
     34                  result);
     35 
     36      CHECK_EQUAL(FractionToDouble(-numerator, denominator),
     37                  std::copysign(result, -numerator));
     38      CHECK_EQUAL(FractionToDouble(-Int128{numerator}, Int128{denominator}),
     39                  std::copysign(result, -numerator));
     40    }
     41  }
     42 
     43  return true;
     44 }
     45 END_TEST(testFraction_simple)
     46 
     47 // Complex test with values exceeding Number.MAX_SAFE_INTEGER.
     48 BEGIN_TEST(testFraction_complex) {
     49  struct {
     50    int64_t numerator;
     51    int64_t denominator;
     52    double result;
     53  } values[] = {
     54      // Number.MAX_SAFE_INTEGER
     55      {9007199254740991, 2, 4503599627370495.5},
     56      {9007199254740992, 2, 4503599627370496},
     57      {9007199254740993, 2, 4503599627370496.5},
     58 
     59      {INT64_MAX, 2, 4611686018427387903.5},
     60      {INT64_MIN, 2, -4611686018427387904.0},
     61  };
     62 
     63  for (auto [numerator, denominator, result] : values) {
     64    CHECK_EQUAL(FractionToDouble(numerator, denominator), result);
     65    CHECK_EQUAL(FractionToDouble(Int128{numerator}, Int128{denominator}),
     66                result);
     67  }
     68 
     69  return true;
     70 }
     71 END_TEST(testFraction_complex)
     72 
     73 // Complex test with Int128 values exceeding Number.MAX_SAFE_INTEGER.
     74 BEGIN_TEST(testFraction_complex_int128) {
     75  struct {
     76    Int128 numerator;
     77    Int128 denominator;
     78    double result;
     79  } values[] = {
     80      // Divide 1 by a growing divisor.
     81      {Int128{1}, Int128{1'000}, 0.001},
     82      {Int128{1}, Int128{1'000'000}, 0.000'001},
     83      {Int128{1}, Int128{1'000'000'000}, 0.000'000'001},
     84      {Int128{1}, Int128{1'000'000'000'000}, 0.000'000'000'001},
     85      {Int128{1}, Int128{1'000'000'000'000'000}, 0.000'000'000'000'001},
     86      {Int128{1}, Int128{1'000'000'000'000'000'000}, 0.000'000'000'000'000'001},
     87      {Int128{1}, Int128{1'000'000'000'000'000'000} * Int128{1'000},
     88       0.000'000'000'000'000'000'001},
     89      {Int128{1}, Int128{1'000'000'000'000'000'000} * Int128{1'000'000},
     90       0.000'000'000'000'000'000'000'001},
     91      {Int128{1}, Int128{1'000'000'000'000'000'000} * Int128{1'000'000'000},
     92       0.000'000'000'000'000'000'000'000'001},
     93      {Int128{1}, Int128{1'000'000'000'000'000'000} * Int128{1'000'000'000'000},
     94       0.000'000'000'000'000'000'000'000'000'001},
     95      {Int128{1},
     96       Int128{1'000'000'000'000'000'000} * Int128{1'000'000'000'000'000},
     97       0.000'000'000'000'000'000'000'000'000'000'001},
     98      {Int128{1},
     99       Int128{1'000'000'000'000'000'000} * Int128{1'000'000'000'000'000'000},
    100       0.000'000'000'000'000'000'000'000'000'000'000'001},
    101 
    102      // Divide a number not representable as an int64.
    103      {Int128{0x8000'0000} << 64, Int128{1'000},
    104       39614081257132168796771975.1680},
    105      {Int128{0x8000'0000} << 64, Int128{1'000'000},
    106       39614081257132168796771.9751680},
    107      {Int128{0x8000'0000} << 64, Int128{1'000'000'000},
    108       39614081257132168796.7719751680},
    109      {Int128{0x8000'0000} << 64, Int128{1'000'000'000'000},
    110       39614081257132168.7967719751680},
    111      {Int128{0x8000'0000} << 64, Int128{1'000'000'000'000'000},
    112       39614081257132.1687967719751680},
    113      {Int128{0x8000'0000} << 64, Int128{1'000'000'000'000'000'000},
    114       39614081257.1321687967719751680},
    115      {Int128{0x8000'0000} << 64,
    116       Int128{1'000'000'000'000'000'000} * Int128{1'000},
    117       39614081.2571321687967719751680},
    118      {Int128{0x8000'0000} << 64,
    119       Int128{1'000'000'000'000'000'000} * Int128{1'000'000},
    120       39614.0812571321687967719751680},
    121      {Int128{0x8000'0000} << 64,
    122       Int128{1'000'000'000'000'000'000} * Int128{1'000'000'000},
    123       39.6140812571321687967719751680},
    124      {Int128{0x8000'0000} << 64,
    125       Int128{1'000'000'000'000'000'000} * Int128{1'000'000'000'000},
    126       0.0396140812571321687967719751680},
    127      {Int128{0x8000'0000} << 64,
    128       Int128{1'000'000'000'000'000'000} * Int128{1'000'000'000'000'000},
    129       0.0000396140812571321687967719751680},
    130      {Int128{0x8000'0000} << 64,
    131       Int128{1'000'000'000'000'000'000} * Int128{1'000'000'000'000'000'000},
    132       0.0000000396140812571321687967719751680},
    133 
    134      // Test divisor which isn't a multiple of ten.
    135      {Int128{0x8000'0000} << 64, Int128{2}, 19807040628566084398385987584.0},
    136      {Int128{0x8000'0000} << 64, Int128{3}, 13204693752377389598923991722.666},
    137      {Int128{0x8000'0000} << 64, Int128{3'333},
    138       11885412918431493788410433.5937},
    139      {Int128{0x8000'0000} << 64, Int128{3'333'333},
    140       11884225565562207195252.3120756},
    141      {Int128{0x8000'0000} << 64, Int128{3'333'333'333},
    142       11884224378328073076.864399858},
    143      {Int128{0x8000'0000} << 64, Int128{3'333'333'333'333},
    144       11884224377140839.0614693066343},
    145      {Int128{0x8000'0000} << 64, Int128{3'333'333'333'333'333},
    146       11884224377139.6518274540302643},
    147      {Int128{0x8000'0000} << 64, Int128{3'333'333'333'333'333'333},
    148       11884224377.1396506402200149881},
    149      {Int128{0x8000'0000} << 64,
    150       (Int128{3'333'333'333'333'333'333} * Int128{1'000}) + Int128{333},
    151       11884224.3771396506390327809728},
    152      {Int128{0x8000'0000} << 64,
    153       (Int128{3'333'333'333'333'333'333} * Int128{1'000'000}) +
    154           Int128{333'333},
    155       11884.2243771396506390315937388},
    156      {Int128{0x8000'0000} << 64,
    157       (Int128{3'333'333'333'333'333'333} * Int128{1'000'000'000}) +
    158           Int128{333'333'333},
    159       11.884224377139650639031592551588422437713965063903159255158842243},
    160      {Int128{0x8000'0000} << 64,
    161       (Int128{3'333'333'333'333'333'333} * Int128{1'000'000'000'000}) +
    162           Int128{333'333'333'333},
    163       0.0118842243771396506390315925504},
    164      {Int128{0x8000'0000} << 64,
    165       (Int128{3'333'333'333'333'333'333} * Int128{1'000'000'000'000'000}) +
    166           Int128{333'333'333'333'333},
    167       0.0000118842243771396506390315925504},
    168      {Int128{0x8000'0000} << 64,
    169       (Int128{3'333'333'333'333'333'333} * Int128{1'000'000'000'000'000'000}) +
    170           Int128{333'333'333'333'333'333},
    171       0.0000000118842243771396506390315925504},
    172  };
    173 
    174  for (auto [numerator, denominator, result] : values) {
    175    CHECK_EQUAL(FractionToDouble(numerator, denominator), result);
    176  }
    177 
    178  return true;
    179 }
    180 END_TEST(testFraction_complex_int128)
    181 
    182 #endif