Last active
February 24, 2020 08:43
-
-
Save 0x4C4A/afca2e5712692d3c8cc1627261de226e to your computer and use it in GitHub Desktop.
nextafter implemented in vanilla js without dependancies
This file contains 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
// nextafter implemented in vanilla js without dependancies | |
// No license, use as you wish. | |
function nextafter(from, to){ | |
if(isNaN(from) || isNaN(to)) | |
return NaN; | |
if(from === to) | |
return to; | |
if(from === 0) | |
return (to > 0) ? Number.MIN_VALUE : -Number.MIN_VALUE; | |
const needToIncrement = (to > from) === (from > 0); | |
return incrementOrDecrementFloat(from, needToIncrement); | |
function incrementOrDecrementFloat(float, increment){ | |
const floatFormat = new Float64Array(1); | |
const uintFormat = new Uint32Array(floatFormat.buffer); | |
const maxUint32Value = 0xFFFFFFFF; | |
floatFormat[0] = 1.0; | |
const littleEndian = uintFormat[0] === 0x3FF00000; | |
const highPart = littleEndian ? 0 : 1; | |
const lowPart = littleEndian ? 1 : 0; | |
floatFormat[0] = float; | |
if(increment){ | |
if(uintFormat[lowPart] === maxUint32Value){ | |
uintFormat[highPart]++; | |
uintFormat[lowPart] = 0; | |
} | |
else{ | |
uintFormat[lowPart]++; | |
} | |
} | |
else{ | |
if(uintFormat[lowPart] === 0){ | |
uintFormat[highPart]--; | |
uintFormat[lowPart] = maxUint32Value; | |
} | |
else{ | |
uintFormat[lowPart]--; | |
} | |
} | |
return floatFormat[0]; | |
} | |
} | |
function testNextAfter(){ | |
console.assert(nextafter(Infinity,Infinity) === Infinity); | |
console.assert(nextafter(Infinity,-1) === Number.MAX_VALUE); | |
console.assert(nextafter(-Infinity,+1) === -Number.MAX_VALUE); | |
console.assert(nextafter(-Infinity,-Infinity) === -Infinity); | |
console.assert(isNaN(nextafter(NaN, 0))); | |
console.assert(isNaN(nextafter(NaN, NaN))); | |
console.assert(isNaN(nextafter(0, NaN))); | |
console.assert(nextafter(0,1.33) === Number.MIN_VALUE); | |
console.assert(nextafter(0,-989) === -Number.MIN_VALUE); | |
console.assert(nextafter(-0,0) === 0); | |
console.assert(nextafter(1923,1) === 1922.9999999999998); | |
console.assert(nextafter(1923,1) === 1922.9999999999998); | |
console.assert(nextafter(-1123123,11) === -1123122.9999999998); | |
console.assert(nextafter(999.1233333,11111) === 999.1233333000001); | |
console.assert(nextafter(-10, -99) === -10.000000000000002); | |
} | |
function printFloatHex(float){ | |
const floatFormat = new Float64Array(1); | |
const uintFormat = new Uint32Array(floatFormat.buffer); | |
floatFormat[0] = float; | |
console.log(uintFormat[1].toString(16).padStart(8, '0'), uintFormat[0].toString(16).padStart(8, '0')) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment