mirror of
https://github.com/tc39/test262.git
synced 2025-07-27 07:54:41 +02:00
Import SpiderMonkey Temporal tests
Temporal tests written for the SpiderMonkey implementation. Mostly covers edge cases around mathematical operations and regression tests for reported spec bugs.
This commit is contained in:
parent
46c3823117
commit
e292fb80de
@ -0,0 +1,77 @@
|
|||||||
|
// Copyright (C) 2022 André Bargull. All rights reserved.
|
||||||
|
// This code is governed by the BSD license found in the LICENSE file.
|
||||||
|
|
||||||
|
/*---
|
||||||
|
esid: sec-temporal.zoneddatetime.prototype.round
|
||||||
|
description: >
|
||||||
|
NanosecondsToDays computes with precise mathematical integers.
|
||||||
|
info: |
|
||||||
|
NanosecondsToDays ( nanoseconds, relativeTo )
|
||||||
|
...
|
||||||
|
14. If sign is 1, then
|
||||||
|
a. Repeat, while days > 0 and intermediateNs > endNs,
|
||||||
|
i. Set days to days - 1.
|
||||||
|
ii. ...
|
||||||
|
|
||||||
|
Ensure |days = days - 1| is exact and doesn't loose precision.
|
||||||
|
features: [Temporal]
|
||||||
|
---*/
|
||||||
|
|
||||||
|
var expectedDurationDays = [
|
||||||
|
Number.MAX_SAFE_INTEGER + 4, // 9007199254740996
|
||||||
|
Number.MAX_SAFE_INTEGER + 3, // 9007199254740994
|
||||||
|
Number.MAX_SAFE_INTEGER + 2, // 9007199254740992
|
||||||
|
Number.MAX_SAFE_INTEGER + 1, // 9007199254740992
|
||||||
|
Number.MAX_SAFE_INTEGER + 0, // 9007199254740991
|
||||||
|
Number.MAX_SAFE_INTEGER - 1, // 9007199254740990
|
||||||
|
Number.MAX_SAFE_INTEGER - 2, // 9007199254740989
|
||||||
|
Number.MAX_SAFE_INTEGER - 3, // 9007199254740988
|
||||||
|
Number.MAX_SAFE_INTEGER - 4, // 9007199254740987
|
||||||
|
Number.MAX_SAFE_INTEGER - 5, // 9007199254740986
|
||||||
|
];
|
||||||
|
|
||||||
|
// Intentionally not Test262Error to ensure assertions errors are propagated.
|
||||||
|
class StopExecution extends Error {}
|
||||||
|
|
||||||
|
var cal = new class extends Temporal.Calendar {
|
||||||
|
#dateUntil = 0;
|
||||||
|
|
||||||
|
dateUntil(one, two, options) {
|
||||||
|
if (++this.#dateUntil === 1) {
|
||||||
|
return Temporal.Duration.from({days: Number.MAX_SAFE_INTEGER + 4});
|
||||||
|
}
|
||||||
|
return super.dateUntil(one, two, options);
|
||||||
|
}
|
||||||
|
|
||||||
|
#dateAdd = 0;
|
||||||
|
|
||||||
|
dateAdd(date, duration, options) {
|
||||||
|
// Ensure we don't add too many days which would lead to creating an invalid date.
|
||||||
|
if (++this.#dateAdd === 3) {
|
||||||
|
assert.sameValue(duration.days, Number.MAX_SAFE_INTEGER + 4);
|
||||||
|
|
||||||
|
// The added days must be larger than 5 for the |intermediateNs > endNs| condition.
|
||||||
|
return super.dateAdd(date, "P6D", options);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ensure the duration days are exact.
|
||||||
|
if (this.#dateAdd > 3) {
|
||||||
|
if (!expectedDurationDays.length) {
|
||||||
|
throw new StopExecution();
|
||||||
|
}
|
||||||
|
assert.sameValue(duration.days, expectedDurationDays.shift());
|
||||||
|
|
||||||
|
// Add more than 5 for the |intermediateNs > endNs| condition.
|
||||||
|
return super.dateAdd(date, "P6D", options);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Otherwise call the default implementation.
|
||||||
|
return super.dateAdd(date, duration, options);
|
||||||
|
}
|
||||||
|
}("iso8601");
|
||||||
|
|
||||||
|
var zoned = new Temporal.ZonedDateTime(0n, "UTC", cal);
|
||||||
|
var duration = Temporal.Duration.from({days: 5});
|
||||||
|
var options = {smallestUnit: "days", relativeTo: zoned};
|
||||||
|
|
||||||
|
assert.throws(StopExecution, () => duration.round(options));
|
@ -0,0 +1,45 @@
|
|||||||
|
// Copyright (C) 2022 André Bargull. All rights reserved.
|
||||||
|
// This code is governed by the BSD license found in the LICENSE file.
|
||||||
|
|
||||||
|
/*---
|
||||||
|
esid: sec-temporal.zoneddatetime.prototype.round
|
||||||
|
description: >
|
||||||
|
NanosecondsToDays computes with precise mathematical integers.
|
||||||
|
info: |
|
||||||
|
NanosecondsToDays ( nanoseconds, relativeTo )
|
||||||
|
...
|
||||||
|
17. Repeat, while done is false,
|
||||||
|
...
|
||||||
|
c. If (nanoseconds - dayLengthNs) × sign ≥ 0, then
|
||||||
|
...
|
||||||
|
iii. Set days to days + sign.
|
||||||
|
|
||||||
|
Ensure |days = days + sign| is exact and doesn't loose precision.
|
||||||
|
features: [Temporal]
|
||||||
|
---*/
|
||||||
|
|
||||||
|
var cal = new class extends Temporal.Calendar {
|
||||||
|
#dateUntil = 0;
|
||||||
|
|
||||||
|
dateUntil(one, two, options) {
|
||||||
|
if (++this.#dateUntil === 1) {
|
||||||
|
return Temporal.Duration.from({days: Number.MAX_SAFE_INTEGER + 10});
|
||||||
|
}
|
||||||
|
return super.dateUntil(one, two, options);
|
||||||
|
}
|
||||||
|
|
||||||
|
#dateAdd = 0;
|
||||||
|
|
||||||
|
dateAdd(date, duration, options) {
|
||||||
|
if (++this.#dateAdd === 3) {
|
||||||
|
return super.dateAdd(date, "P1D", options);
|
||||||
|
}
|
||||||
|
return super.dateAdd(date, duration, options);
|
||||||
|
}
|
||||||
|
}("iso8601");
|
||||||
|
|
||||||
|
var zoned = new Temporal.ZonedDateTime(0n, "UTC", cal);
|
||||||
|
var duration = Temporal.Duration.from({days: 5});
|
||||||
|
var result = duration.round({smallestUnit: "days", relativeTo: zoned});
|
||||||
|
|
||||||
|
assert.sameValue(result.days, Number(BigInt(Number.MAX_SAFE_INTEGER + 10) + 5n));
|
96
test/built-ins/Temporal/Duration/prototype/total/precision-exact-mathematical-values-1.js
vendored
Normal file
96
test/built-ins/Temporal/Duration/prototype/total/precision-exact-mathematical-values-1.js
vendored
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
// Copyright (C) 2022 André Bargull. All rights reserved.
|
||||||
|
// This code is governed by the BSD license found in the LICENSE file.
|
||||||
|
|
||||||
|
/*---
|
||||||
|
esid: sec-temporal.duration.prototype.total
|
||||||
|
description: >
|
||||||
|
RoundDuration computes on exact mathematical values.
|
||||||
|
features: [Temporal]
|
||||||
|
---*/
|
||||||
|
|
||||||
|
// Return the next Number value in direction to +Infinity.
|
||||||
|
function nextUp(num) {
|
||||||
|
if (!Number.isFinite(num)) {
|
||||||
|
return num;
|
||||||
|
}
|
||||||
|
if (num === 0) {
|
||||||
|
return Number.MIN_VALUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
var f64 = new Float64Array([num]);
|
||||||
|
var u64 = new BigUint64Array(f64.buffer);
|
||||||
|
u64[0] += (num < 0 ? -1n : 1n);
|
||||||
|
return f64[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return the next Number value in direction to -Infinity.
|
||||||
|
function nextDown(num) {
|
||||||
|
if (!Number.isFinite(num)) {
|
||||||
|
return num;
|
||||||
|
}
|
||||||
|
if (num === 0) {
|
||||||
|
return -Number.MIN_VALUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
var f64 = new Float64Array([num]);
|
||||||
|
var u64 = new BigUint64Array(f64.buffer);
|
||||||
|
u64[0] += (num < 0 ? 1n : -1n);
|
||||||
|
return f64[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
let duration = Temporal.Duration.from({
|
||||||
|
hours: 4000,
|
||||||
|
nanoseconds: 1,
|
||||||
|
});
|
||||||
|
|
||||||
|
let total = duration.total({unit: "hours"});
|
||||||
|
|
||||||
|
// From RoundDuration():
|
||||||
|
//
|
||||||
|
// 7. Let fractionalSeconds be nanoseconds × 10^-9 + microseconds × 10^-6 + milliseconds × 10^-3 + seconds.
|
||||||
|
// = nanoseconds × 10^-9
|
||||||
|
// = 1 × 10^-9
|
||||||
|
// = 10^-9
|
||||||
|
// = 0.000000001
|
||||||
|
//
|
||||||
|
// 13.a. Let fractionalHours be (fractionalSeconds / 60 + minutes) / 60 + hours.
|
||||||
|
// = (fractionalSeconds / 60) / 60 + 4000
|
||||||
|
// = 0.000000001 / 3600 + 4000
|
||||||
|
//
|
||||||
|
// 13.b. Set hours to RoundNumberToIncrement(fractionalHours, increment, roundingMode).
|
||||||
|
// = trunc(fractionalHours)
|
||||||
|
// = trunc(0.000000001 / 3600 + 4000)
|
||||||
|
// = 4000
|
||||||
|
//
|
||||||
|
// 13.c. Set remainder to fractionalHours - hours.
|
||||||
|
// = fractionalHours - hours
|
||||||
|
// = 0.000000001 / 3600 + 4000 - 4000
|
||||||
|
// = 0.000000001 / 3600
|
||||||
|
//
|
||||||
|
// From Temporal.Duration.prototype.total ( options ):
|
||||||
|
//
|
||||||
|
// 18. If unit is "hours", then let whole be roundResult.[[Hours]].
|
||||||
|
// ...
|
||||||
|
// 24. Return whole + roundResult.[[Remainder]].
|
||||||
|
//
|
||||||
|
// |whole| is 4000 and the remainder is (0.000000001 / 3600).
|
||||||
|
//
|
||||||
|
// 0.000000001 / 3600
|
||||||
|
// = (1 / 10^9) / 3600
|
||||||
|
// = (1 / 36) / 10^11
|
||||||
|
// = 0.02777.... / 10^11
|
||||||
|
// = 0.0000000000002777...
|
||||||
|
//
|
||||||
|
// 4000.0000000000002777... can't be represented exactly, the next best approximation
|
||||||
|
// is 4000.0000000000005.
|
||||||
|
|
||||||
|
const expected = 4000.0000000000005;
|
||||||
|
assert.sameValue(expected, 4000.0000000000002777);
|
||||||
|
|
||||||
|
// The next Number in direction -Infinity is less precise.
|
||||||
|
assert.sameValue(nextDown(expected), 4000);
|
||||||
|
|
||||||
|
// The next Number in direction +Infinity is less precise.
|
||||||
|
assert.sameValue(nextUp(expected), 4000.000000000001);
|
||||||
|
|
||||||
|
assert.sameValue(total, expected);
|
98
test/built-ins/Temporal/Duration/prototype/total/precision-exact-mathematical-values-2.js
vendored
Normal file
98
test/built-ins/Temporal/Duration/prototype/total/precision-exact-mathematical-values-2.js
vendored
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
// Copyright (C) 2022 André Bargull. All rights reserved.
|
||||||
|
// This code is governed by the BSD license found in the LICENSE file.
|
||||||
|
|
||||||
|
/*---
|
||||||
|
esid: sec-temporal.duration.prototype.total
|
||||||
|
description: >
|
||||||
|
RoundDuration computes on exact mathematical values.
|
||||||
|
features: [Temporal]
|
||||||
|
---*/
|
||||||
|
|
||||||
|
// Return the next Number value in direction to +Infinity.
|
||||||
|
function nextUp(num) {
|
||||||
|
if (!Number.isFinite(num)) {
|
||||||
|
return num;
|
||||||
|
}
|
||||||
|
if (num === 0) {
|
||||||
|
return Number.MIN_VALUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
var f64 = new Float64Array([num]);
|
||||||
|
var u64 = new BigUint64Array(f64.buffer);
|
||||||
|
u64[0] += (num < 0 ? -1n : 1n);
|
||||||
|
return f64[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return the next Number value in direction to -Infinity.
|
||||||
|
function nextDown(num) {
|
||||||
|
if (!Number.isFinite(num)) {
|
||||||
|
return num;
|
||||||
|
}
|
||||||
|
if (num === 0) {
|
||||||
|
return -Number.MIN_VALUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
var f64 = new Float64Array([num]);
|
||||||
|
var u64 = new BigUint64Array(f64.buffer);
|
||||||
|
u64[0] += (num < 0 ? 1n : -1n);
|
||||||
|
return f64[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
let duration = Temporal.Duration.from({
|
||||||
|
hours: 4000,
|
||||||
|
minutes: 59,
|
||||||
|
seconds: 59,
|
||||||
|
milliseconds: 999,
|
||||||
|
microseconds: 999,
|
||||||
|
nanoseconds: 999,
|
||||||
|
});
|
||||||
|
|
||||||
|
let total = duration.total({unit: "hours"});
|
||||||
|
|
||||||
|
// From RoundDuration():
|
||||||
|
//
|
||||||
|
// 7. Let fractionalSeconds be nanoseconds × 10^-9 + microseconds × 10^-6 + milliseconds × 10^-3 + seconds.
|
||||||
|
// = 999 × 10^-9 + 999 × 10^-6 + 999 × 10^-3 + 59
|
||||||
|
// = 59.999'999'999
|
||||||
|
//
|
||||||
|
// 13.a. Let fractionalHours be (fractionalSeconds / 60 + minutes) / 60 + hours.
|
||||||
|
// = (59.999'999'999 / 60 + 59) / 60 + 4000
|
||||||
|
// = 1 - 0.000000001 / 3600 + 4000
|
||||||
|
//
|
||||||
|
// 13.b. Set hours to RoundNumberToIncrement(fractionalHours, increment, roundingMode).
|
||||||
|
// = trunc(fractionalHours)
|
||||||
|
// = trunc(1 - 0.000000001 / 3600 + 4000)
|
||||||
|
// = 4000
|
||||||
|
//
|
||||||
|
// 13.c. Set remainder to fractionalHours - hours.
|
||||||
|
// = fractionalHours - hours
|
||||||
|
// = 1 - 0.000000001 / 3600 + 4000 - 4000
|
||||||
|
// = 1 - 0.000000001 / 3600
|
||||||
|
//
|
||||||
|
// From Temporal.Duration.prototype.total ( options ):
|
||||||
|
//
|
||||||
|
// 18. If unit is "hours", then let whole be roundResult.[[Hours]].
|
||||||
|
// ...
|
||||||
|
// 24. Return whole + roundResult.[[Remainder]].
|
||||||
|
//
|
||||||
|
// |whole| is 4000 and the remainder is (1 - 0.000000001 / 3600).
|
||||||
|
//
|
||||||
|
// 1 - 0.000000001 / 3600
|
||||||
|
// = 1 - (1 / 10^9) / 3600
|
||||||
|
// = 1 - (1 / 36) / 10^11
|
||||||
|
// = 1 - 0.02777.... / 10^11
|
||||||
|
// = 0.9999999999997222...
|
||||||
|
//
|
||||||
|
// 4000.9999999999997222... can't be represented exactly, the next best approximation
|
||||||
|
// is 4000.9999999999995.
|
||||||
|
|
||||||
|
const expected = 4000.9999999999995;
|
||||||
|
assert.sameValue(expected, 4000.9999999999997222);
|
||||||
|
|
||||||
|
// The next Number in direction -Infinity is less precise.
|
||||||
|
assert.sameValue(nextDown(expected), 4000.999999999999);
|
||||||
|
|
||||||
|
// The next Number in direction +Infinity is less precise.
|
||||||
|
assert.sameValue(nextUp(expected), 4001);
|
||||||
|
|
||||||
|
assert.sameValue(total, expected);
|
130
test/built-ins/Temporal/ZonedDateTime/prototype/hoursInDay/precision-exact-mathematical-values.js
vendored
Normal file
130
test/built-ins/Temporal/ZonedDateTime/prototype/hoursInDay/precision-exact-mathematical-values.js
vendored
Normal file
@ -0,0 +1,130 @@
|
|||||||
|
// Copyright (C) 2022 André Bargull. All rights reserved.
|
||||||
|
// This code is governed by the BSD license found in the LICENSE file.
|
||||||
|
|
||||||
|
/*---
|
||||||
|
esid: sec-get-temporal.zoneddatetime.prototype.hoursinday
|
||||||
|
description: >
|
||||||
|
Hours in day is correctly rounded using precise mathematical values.
|
||||||
|
info: |
|
||||||
|
get Temporal.ZonedDateTime.prototype.hoursInDay
|
||||||
|
|
||||||
|
...
|
||||||
|
15. Let diffNs be tomorrowInstant.[[Nanoseconds]] - todayInstant.[[Nanoseconds]].
|
||||||
|
16. Return 𝔽(diffNs / (3.6 × 10^12)).
|
||||||
|
features: [Temporal]
|
||||||
|
---*/
|
||||||
|
|
||||||
|
const maxInstant = 86_40000_00000_00000_00000n;
|
||||||
|
|
||||||
|
function nextUp(num) {
|
||||||
|
if (!Number.isFinite(num)) {
|
||||||
|
return num;
|
||||||
|
}
|
||||||
|
if (num === 0) {
|
||||||
|
return Number.MIN_VALUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
var f64 = new Float64Array([num]);
|
||||||
|
var u64 = new BigUint64Array(f64.buffer);
|
||||||
|
u64[0] += (num < 0 ? -1n : 1n);
|
||||||
|
return f64[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
function nextDown(num) {
|
||||||
|
if (!Number.isFinite(num)) {
|
||||||
|
return num;
|
||||||
|
}
|
||||||
|
if (num === 0) {
|
||||||
|
return -Number.MIN_VALUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
var f64 = new Float64Array([num]);
|
||||||
|
var u64 = new BigUint64Array(f64.buffer);
|
||||||
|
u64[0] += (num < 0 ? 1n : -1n);
|
||||||
|
return f64[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
function BigIntAbs(n) {
|
||||||
|
return n >= 0 ? n : -n;
|
||||||
|
}
|
||||||
|
|
||||||
|
function test(todayInstant, tomorrowInstant, expected) {
|
||||||
|
let timeZone = new class extends Temporal.TimeZone {
|
||||||
|
#getPossibleInstantsFor = 0;
|
||||||
|
|
||||||
|
getPossibleInstantsFor() {
|
||||||
|
if (++this.#getPossibleInstantsFor === 1) {
|
||||||
|
return [new Temporal.Instant(todayInstant)];
|
||||||
|
}
|
||||||
|
assert.sameValue(this.#getPossibleInstantsFor, 2);
|
||||||
|
return [new Temporal.Instant(tomorrowInstant)];
|
||||||
|
}
|
||||||
|
}("UTC");
|
||||||
|
|
||||||
|
let zdt = new Temporal.ZonedDateTime(0n, timeZone);
|
||||||
|
let zdt_hoursInDay = zdt.hoursInDay;
|
||||||
|
|
||||||
|
assert.sameValue(zdt_hoursInDay, expected);
|
||||||
|
|
||||||
|
// Ensure the |expected| value is actually correctly rounded.
|
||||||
|
|
||||||
|
const nsPerSec = 1000n * 1000n * 1000n;
|
||||||
|
const secPerHour = 60n * 60n;
|
||||||
|
const nsPerHour = secPerHour * nsPerSec;
|
||||||
|
|
||||||
|
function toNanoseconds(hours) {
|
||||||
|
let wholeHours = BigInt(Math.trunc(hours)) * nsPerHour;
|
||||||
|
let fractionalHours = BigInt(Math.trunc(hours % 1 * Number(nsPerHour)));
|
||||||
|
return wholeHours + fractionalHours;
|
||||||
|
}
|
||||||
|
|
||||||
|
let diff = tomorrowInstant - todayInstant;
|
||||||
|
let nanosInDay = toNanoseconds(zdt_hoursInDay);
|
||||||
|
|
||||||
|
// The next number gives a less precise result.
|
||||||
|
let next = toNanoseconds(nextUp(zdt_hoursInDay));
|
||||||
|
assert(BigIntAbs(diff - nanosInDay) <= BigIntAbs(diff - next));
|
||||||
|
|
||||||
|
// The previous number gives a less precise result.
|
||||||
|
let prev = toNanoseconds(nextDown(zdt_hoursInDay));
|
||||||
|
assert(BigIntAbs(diff - nanosInDay) <= BigIntAbs(diff - prev));
|
||||||
|
|
||||||
|
// This computation can be inaccurate.
|
||||||
|
let inaccurate = Number(diff) / Number(nsPerHour);
|
||||||
|
|
||||||
|
// Doing it component-wise can produce more accurate results.
|
||||||
|
let hours = Number(diff / nsPerSec) / Number(secPerHour);
|
||||||
|
let fractionalHours = Number(diff % nsPerSec) / Number(nsPerHour);
|
||||||
|
assert.sameValue(hours + fractionalHours, expected);
|
||||||
|
|
||||||
|
// Ensure the result is more precise than the inaccurate result.
|
||||||
|
let inaccurateNanosInDay = toNanoseconds(inaccurate);
|
||||||
|
assert(BigIntAbs(diff - nanosInDay) <= BigIntAbs(diff - inaccurateNanosInDay));
|
||||||
|
}
|
||||||
|
|
||||||
|
test(-maxInstant, 0n, 2400000000);
|
||||||
|
test(-maxInstant, 1n, 2400000000);
|
||||||
|
test(-maxInstant, 10n, 2400000000);
|
||||||
|
test(-maxInstant, 100n, 2400000000);
|
||||||
|
|
||||||
|
test(-maxInstant, 1_000n, 2400000000);
|
||||||
|
test(-maxInstant, 10_000n, 2400000000);
|
||||||
|
test(-maxInstant, 100_000n, 2400000000);
|
||||||
|
|
||||||
|
test(-maxInstant, 1_000_000n, 2400000000.0000005);
|
||||||
|
test(-maxInstant, 10_000_000n, 2400000000.000003);
|
||||||
|
test(-maxInstant, 100_000_000n, 2400000000.0000277);
|
||||||
|
|
||||||
|
test(-maxInstant, 1_000_000_000n, 2400000000.000278);
|
||||||
|
test(-maxInstant, 10_000_000_000n, 2400000000.0027776);
|
||||||
|
test(-maxInstant, 100_000_000_000n, 2400000000.0277777);
|
||||||
|
|
||||||
|
test(-maxInstant, maxInstant, 4800000000);
|
||||||
|
test(-maxInstant, maxInstant - 10_000_000_000n, 4799999999.997222);
|
||||||
|
test(-maxInstant, maxInstant - 10_000_000_000n + 1n, 4799999999.997222);
|
||||||
|
test(-maxInstant, maxInstant - 10_000_000_000n - 1n, 4799999999.997222);
|
||||||
|
|
||||||
|
test(maxInstant, -maxInstant, -4800000000);
|
||||||
|
test(maxInstant, -(maxInstant - 10_000_000_000n), -4799999999.997222);
|
||||||
|
test(maxInstant, -(maxInstant - 10_000_000_000n + 1n), -4799999999.997222);
|
||||||
|
test(maxInstant, -(maxInstant - 10_000_000_000n - 1n), -4799999999.997222);
|
Loading…
x
Reference in New Issue
Block a user