Last active
January 14, 2019 14:51
-
-
Save grind086/5990400c9ca8c81e31927fda2a1cacc7 to your computer and use it in GitHub Desktop.
Adding data to NaN values
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
console.log(examineNaN(NaN)); | |
// > { isNaN: true, sign: 0, signaling: false, payload: 0 } | |
const nan = createNaN(false, false, 5000); | |
console.log(isNaN(nan)); | |
// > true | |
console.log(examineNaN(nan)); | |
// > { isNaN: true, sign: 0, signaling: false, payload: 5000 } | |
const nan2 = createNaN(false, false, [1, 2, 3, 4, 5, 6]); | |
console.log(isNaN(nan2)); | |
// > true | |
console.log(examineNaN(nan2)); | |
// > { isNaN: true, sign: 0, signaling: false, payload: Uint8Array [ 1, 2, 3, 4, 5, 6 ] } | |
console.log(examineNaN(nan + 3).payload === examineNaN(nan).payload); | |
// > true |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* @param {boolean} sign false is positive, true is negative | |
* @param {boolean} signaling Whether or not this is a signaling NaN | |
* @param {number | number[] | Uint8Array} payload A single 32-bit integer or an array of up to 6 bytes. | |
*/ | |
function createNaN(sign, signaling, payload) { | |
const buf = new ArrayBuffer(8); | |
const view = new DataView(buf); | |
const isByteArray = !('number' === typeof payload); | |
if (isByteArray) { | |
const byteCount = Math.min(6, payload.length); | |
for (let i = 0; i < byteCount; i++) { | |
view.setUint8(i + 2, payload[i]); | |
} | |
} else { | |
view.setUint32(4, parseInt(payload), false); | |
} | |
view.setUint8(0, (sign << 7) | 0b01111111); | |
view.setUint8(1, 0b11110100 | ((!signaling) << 3) | isByteArray); | |
return view.getFloat64(0); | |
} | |
/** | |
* @param {number} value | |
*/ | |
function examineNaN(value) { | |
const buf = new ArrayBuffer(8); | |
const view = new DataView(buf); | |
view.setFloat64(0, value); | |
const ui8_0 = view.getUint8(0); | |
const ui8_1 = view.getUint8(1); | |
const signValue = (ui8_0 & 0b10000000) >> 7; | |
const signalingValue = ui8_1 & 0b00001000; | |
const exponentValue = ((ui8_0 & 0b011111111) << 4) | ((ui8_1 & 0b11110000) >> 4); | |
view.setUint8(0, 0); | |
view.setUint8(1, ui8_1 & 0b00001111); | |
const significandValue = view.getFloat64(0); | |
const isNaNValue = !!significandValue && exponentValue === 2047; | |
const isByteArray = (ui8_1 & 0b00000001); | |
return { | |
isNaN: isNaNValue, | |
sign: signValue, | |
signaling: isNaNValue ? !signalingValue : undefined, | |
payload: isNaNValue ? (isByteArray ? new Uint8Array(buf, 2, 6) : view.getUint32(4, false)) : undefined | |
}; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment