Bug 1874684 - Part 22: Compute the precise fraction in Duration.p.total and ZonedDate...
[gecko.git] / js / src / jsapi-tests / testFractionToDouble.cpp
blobc3e6842863dda990f0abe775f4b45603d936c8d9
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/. */
5 #ifdef JS_HAS_TEMPORAL_API
7 # include <cmath>
8 # include <stdint.h>
10 # include "builtin/temporal/Int128.h"
11 # include "builtin/temporal/Temporal.h"
12 # include "jsapi-tests/tests.h"
14 using namespace js::temporal;
16 // Simple test using numerators and denominators where the result can be
17 // computed through standard double division.
18 BEGIN_TEST(testFraction_simple) {
19 int64_t numerators[] = {
20 0, 1, 2, 10, 100, INT32_MIN, INT32_MAX,
23 int64_t denominators[] = {
24 1, 2, 3, 10, 100, 1000,
27 for (auto numerator : numerators) {
28 for (auto denominator : denominators) {
29 double result = double(numerator) / double(denominator);
31 CHECK_EQUAL(FractionToDouble(numerator, denominator), result);
32 CHECK_EQUAL(FractionToDouble(Int128{numerator}, Int128{denominator}),
33 result);
35 CHECK_EQUAL(FractionToDouble(-numerator, denominator),
36 std::copysign(result, -numerator));
37 CHECK_EQUAL(FractionToDouble(-Int128{numerator}, Int128{denominator}),
38 std::copysign(result, -numerator));
42 return true;
44 END_TEST(testFraction_simple)
46 // Complex test with values exceeding Number.MAX_SAFE_INTEGER.
47 BEGIN_TEST(testFraction_complex) {
48 struct {
49 int64_t numerator;
50 int64_t denominator;
51 double result;
52 } values[] = {
53 // Number.MAX_SAFE_INTEGER
54 {9007199254740991, 2, 4503599627370495.5},
55 {9007199254740992, 2, 4503599627370496},
56 {9007199254740993, 2, 4503599627370496.5},
58 {INT64_MAX, 2, 4611686018427387903.5},
59 {INT64_MIN, 2, -4611686018427387904.0},
62 for (auto [numerator, denominator, result] : values) {
63 CHECK_EQUAL(FractionToDouble(numerator, denominator), result);
64 CHECK_EQUAL(FractionToDouble(Int128{numerator}, Int128{denominator}),
65 result);
68 return true;
70 END_TEST(testFraction_complex)
72 // Complex test with Int128 values exceeding Number.MAX_SAFE_INTEGER.
73 BEGIN_TEST(testFraction_complex_int128) {
74 struct {
75 Int128 numerator;
76 Int128 denominator;
77 double result;
78 } values[] = {
79 // Divide 1 by a growing divisor.
80 {Int128{1}, Int128{1'000}, 0.001},
81 {Int128{1}, Int128{1'000'000}, 0.000'001},
82 {Int128{1}, Int128{1'000'000'000}, 0.000'000'001},
83 {Int128{1}, Int128{1'000'000'000'000}, 0.000'000'000'001},
84 {Int128{1}, Int128{1'000'000'000'000'000}, 0.000'000'000'000'001},
85 {Int128{1}, Int128{1'000'000'000'000'000'000}, 0.000'000'000'000'000'001},
86 {Int128{1}, Int128{1'000'000'000'000'000'000} * Int128{1'000},
87 0.000'000'000'000'000'000'001},
88 {Int128{1}, Int128{1'000'000'000'000'000'000} * Int128{1'000'000},
89 0.000'000'000'000'000'000'000'001},
90 {Int128{1}, Int128{1'000'000'000'000'000'000} * Int128{1'000'000'000},
91 0.000'000'000'000'000'000'000'000'001},
92 {Int128{1}, Int128{1'000'000'000'000'000'000} * Int128{1'000'000'000'000},
93 0.000'000'000'000'000'000'000'000'000'001},
94 {Int128{1},
95 Int128{1'000'000'000'000'000'000} * Int128{1'000'000'000'000'000},
96 0.000'000'000'000'000'000'000'000'000'000'001},
97 {Int128{1},
98 Int128{1'000'000'000'000'000'000} * Int128{1'000'000'000'000'000'000},
99 0.000'000'000'000'000'000'000'000'000'000'000'001},
101 // Divide a number not representable as an int64.
102 {Int128{0x8000'0000} << 64, Int128{1'000},
103 39614081257132168796771975.1680},
104 {Int128{0x8000'0000} << 64, Int128{1'000'000},
105 39614081257132168796771.9751680},
106 {Int128{0x8000'0000} << 64, Int128{1'000'000'000},
107 39614081257132168796.7719751680},
108 {Int128{0x8000'0000} << 64, Int128{1'000'000'000'000},
109 39614081257132168.7967719751680},
110 {Int128{0x8000'0000} << 64, Int128{1'000'000'000'000'000},
111 39614081257132.1687967719751680},
112 {Int128{0x8000'0000} << 64, Int128{1'000'000'000'000'000'000},
113 39614081257.1321687967719751680},
114 {Int128{0x8000'0000} << 64,
115 Int128{1'000'000'000'000'000'000} * Int128{1'000},
116 39614081.2571321687967719751680},
117 {Int128{0x8000'0000} << 64,
118 Int128{1'000'000'000'000'000'000} * Int128{1'000'000},
119 39614.0812571321687967719751680},
120 {Int128{0x8000'0000} << 64,
121 Int128{1'000'000'000'000'000'000} * Int128{1'000'000'000},
122 39.6140812571321687967719751680},
123 {Int128{0x8000'0000} << 64,
124 Int128{1'000'000'000'000'000'000} * Int128{1'000'000'000'000},
125 0.0396140812571321687967719751680},
126 {Int128{0x8000'0000} << 64,
127 Int128{1'000'000'000'000'000'000} * Int128{1'000'000'000'000'000},
128 0.0000396140812571321687967719751680},
129 {Int128{0x8000'0000} << 64,
130 Int128{1'000'000'000'000'000'000} * Int128{1'000'000'000'000'000'000},
131 0.0000000396140812571321687967719751680},
133 // Test divisor which isn't a multiple of ten.
134 {Int128{0x8000'0000} << 64, Int128{2}, 19807040628566084398385987584.0},
135 {Int128{0x8000'0000} << 64, Int128{3}, 13204693752377389598923991722.666},
136 {Int128{0x8000'0000} << 64, Int128{3'333},
137 11885412918431493788410433.5937},
138 {Int128{0x8000'0000} << 64, Int128{3'333'333},
139 11884225565562207195252.3120756},
140 {Int128{0x8000'0000} << 64, Int128{3'333'333'333},
141 11884224378328073076.864399858},
142 {Int128{0x8000'0000} << 64, Int128{3'333'333'333'333},
143 11884224377140839.0614693066343},
144 {Int128{0x8000'0000} << 64, Int128{3'333'333'333'333'333},
145 11884224377139.6518274540302643},
146 {Int128{0x8000'0000} << 64, Int128{3'333'333'333'333'333'333},
147 11884224377.1396506402200149881},
148 {Int128{0x8000'0000} << 64,
149 (Int128{3'333'333'333'333'333'333} * Int128{1'000}) + Int128{333},
150 11884224.3771396506390327809728},
151 {Int128{0x8000'0000} << 64,
152 (Int128{3'333'333'333'333'333'333} * Int128{1'000'000}) +
153 Int128{333'333},
154 11884.2243771396506390315937388},
155 {Int128{0x8000'0000} << 64,
156 (Int128{3'333'333'333'333'333'333} * Int128{1'000'000'000}) +
157 Int128{333'333'333},
158 11.884224377139650639031592551588422437713965063903159255158842243},
159 {Int128{0x8000'0000} << 64,
160 (Int128{3'333'333'333'333'333'333} * Int128{1'000'000'000'000}) +
161 Int128{333'333'333'333},
162 0.0118842243771396506390315925504},
163 {Int128{0x8000'0000} << 64,
164 (Int128{3'333'333'333'333'333'333} * Int128{1'000'000'000'000'000}) +
165 Int128{333'333'333'333'333},
166 0.0000118842243771396506390315925504},
167 {Int128{0x8000'0000} << 64,
168 (Int128{3'333'333'333'333'333'333} * Int128{1'000'000'000'000'000'000}) +
169 Int128{333'333'333'333'333'333},
170 0.0000000118842243771396506390315925504},
173 for (auto [numerator, denominator, result] : values) {
174 CHECK_EQUAL(FractionToDouble(numerator, denominator), result);
177 return true;
179 END_TEST(testFraction_complex_int128)
181 #endif