Open Opened 1 year ago Updated 1 year ago

# Differing results for 10**23 between v8 and SpiderMonkey

P3
N/A

NEW

## Details

Migrated from bug 1316557 comment 1:

I'm having an issue with Math.pow too.
Math.pow(10, 23) and 10 ** 23 returns 1.0000000000000001e+23
On Chrome it's 1e+23, so I'm using Number("1e" + 23) to get consistent results.

This seems like a potential interoperability/fingerprinting issue.

We seem to do better in general (at least under Linux, not sure about the precision of std::pow under Windows/MacOS). The following test case shows more imprecise results for Chrome, cf. https://bugzilla.mozilla.org/show_bug.cgi?id=1775254#c4. As part of bug 1775254, I've also added "pow-approx-pow10.js" in https://phabricator.services.mozilla.com/D150791 to ensure the error is less than 2 ULP for Math.pow(10, i).

for (let i = 0; i <= Math.trunc(Math.log10(Number.MAX_VALUE)); ++i) {
let n = 10 ** i;
let k = Number("1e"+i);

let abs = n => n < 0 ? -n : n;

let e = 10n ** BigInt(i);
let d1 = abs(e - BigInt(n));
let d2 = abs(e - BigInt(k));

// Check the results are consistent.
if ((d1 < d2 && n !== k) || (d2 > d1 && n === k)) {
console.log("inconsistent results");
continue;
}

if (n !== k) {
console.log(i, n, k);

if (d1 > d2) {
console.log("choose wrong");
} else {
// The delta between both points is equal.
console.log("middle point");
}

let ulp = new BigUint64Array(new Float64Array([n]).buffer)[0];
let down = new Float64Array(new BigUint64Array([ulp - 1n]).buffer)[0];
let up = new Float64Array(new BigUint64Array([ulp + 1n]).buffer)[0];

if (down === k) {
console.log("down is better");
} else if (up === k) {
console.log("up is better");
} else {
// Something is wrong if we end up here.
console.log("???");
}
}
}

Fingerprinting is also discussed in bug 1775254, which also links to bug 1722181. Bug 1775254 also introduced a regression due to fingerprinting -> bug 1784111.

Blocks: sm-runtime
Severity: S3 → N/A
Priority: -- → P3