Join GitHub today
GitHub is home to over 28 million developers working together to host and review code, manage projects, and build software together.
Sign up24.1.1.6, 24.1.1.7, non-canonical NaNs #546
Comments
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
allenwb
Apr 19, 2016
Member
For the motivation of that language in the 24.1.1.5 language see https://bugs.ecmascript.org/show_bug.cgi?id=3508#3 and also https://bugs.ecmascript.org/show_bug.cgi?id=4382
What the language is trying to say is that a consistent policy must be applied to storing NaN values into ArrayBuffers. Canonicalization of all NaNs to some single NaN bit-pattern is not required but each distinct NaN value (if multiiple NaN encodings can exist in an implementation as Number values) must be handled in a consistent manner.
Here are two illustrative examples:
let f64a = new Float64Array(1);
let bytes = new Uint8Array(f64a.buffer, 0, 8);
// use some Uint8 level accesses to insert your favorite NaN bit encoding into bytes
let nun = f64a[0];
let f64target = new Float64Array(2);
f64target[0] = num;
f64target[1] = num;
let uintTarget = new Uint8Array(f64.target.buffer, 0, 16);
//assert uintTarget.slice(0,7) and uintTarget.slice(8,15) are the same byte sequences.
//they may or may not be the same as the byte sequence as bytes.slice(0,7)
//example 2
let n1 = NaN+NaN;
let n2 = NaN*NaN;
let f64target1 = new Float64Array(2);
f64target1[0]=n1;
f64target1[1]=n2;
let f64target2 = new Float64Array(2);
f64target2[0]=n1;
f64target2[1]=n2;
let uintTarget1 = new Uint8Array(f64.target1.buffer, 0, 16);
let uintTarget2 = new Uint8Array(f64.target2.buffer, 0, 16);
//assert uintTarget1.slice(0,7) and uintTarget2.slice(0,7) are the same byte sequences.
//assert uintTarget1.slice(8,18) and uintTarget2.slice(8,15) are the same byte sequences.
//It is up to the implementation whether or not uintTarget1.slice(0,7) and uintTarget1.slice(8,15) are the same byte sequences|
For the motivation of that language in the 24.1.1.5 language see https://bugs.ecmascript.org/show_bug.cgi?id=3508#3 and also https://bugs.ecmascript.org/show_bug.cgi?id=4382 What the language is trying to say is that a consistent policy must be applied to storing NaN values into ArrayBuffers. Canonicalization of all NaNs to some single NaN bit-pattern is not required but each distinct NaN value (if multiiple NaN encodings can exist in an implementation as Number values) must be handled in a consistent manner. Here are two illustrative examples: let f64a = new Float64Array(1);
let bytes = new Uint8Array(f64a.buffer, 0, 8);
// use some Uint8 level accesses to insert your favorite NaN bit encoding into bytes
let nun = f64a[0];
let f64target = new Float64Array(2);
f64target[0] = num;
f64target[1] = num;
let uintTarget = new Uint8Array(f64.target.buffer, 0, 16);
//assert uintTarget.slice(0,7) and uintTarget.slice(8,15) are the same byte sequences.
//they may or may not be the same as the byte sequence as bytes.slice(0,7)
//example 2
let n1 = NaN+NaN;
let n2 = NaN*NaN;
let f64target1 = new Float64Array(2);
f64target1[0]=n1;
f64target1[1]=n2;
let f64target2 = new Float64Array(2);
f64target2[0]=n1;
f64target2[1]=n2;
let uintTarget1 = new Uint8Array(f64.target1.buffer, 0, 16);
let uintTarget2 = new Uint8Array(f64.target2.buffer, 0, 16);
//assert uintTarget1.slice(0,7) and uintTarget2.slice(0,7) are the same byte sequences.
//assert uintTarget1.slice(8,18) and uintTarget2.slice(8,15) are the same byte sequences.
//It is up to the implementation whether or not uintTarget1.slice(0,7) and uintTarget1.slice(8,15) are the same byte sequences |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
|
Seems answered. |
pipcet commentedApr 18, 2016
I am wondering whether the current SpiderMonkey asm.js implementation is compliant when it comes to non-canonical NaNs; the current implementation normalizes an NaN stored at address 0 in the Float64Array HEAPF64 when HEAPF64[0] = HEAPF64[0] is executed in normal code, but leaves the NaN non-canonicalized when the same code is compiled as asm.js.
There appears to be an inconsistency in the spec: 24.1.1.6 speaks of the (singular) NaN value while 24.1.1.7 mentions the possibility of there being several "implementation distinguishable NaN values".
My understanding of the specification's intent is that there is a way of implementing a ==== operator on NaNs (i.e. all values with x !== x) such that:
(1) x ==== x
(2) if x ==== y and y ==== z, then x ==== z
(3) x ==== y iff y ==== x
(4) two identical array buffers remain identical if x====y and x and y, respectively, are written to the same address of either buffer.
but not necessarily
(5) if two identical array buffers remain identical after x and y have been written to the same address of either buffer, then x ==== y
We could then refer to two NaNs as implementation-indistinguishable iff x ==== y.
I would suggest the best course of action is to remove the stipulation that "An implementation must always choose the same encoding for each implementation distinguishable NaN value." That would obviate the need to define what implementation distinguishable NaN values are and render the current implementation compliant in this regard.
https://bugzilla.mozilla.org/show_bug.cgi?id=1259280