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