Last active
June 27, 2020 22:43
-
-
Save farzher/bd60c58886ca54f6b161f80cf5c5d891 to your computer and use it in GitHub Desktop.
floating precision positive whole numbers using arbitrary mantissa / exponent sizes
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
function tomyfloat(mbits, ebits, value) { | |
if(mbits + ebits > 31) throw new Error('no support for > 31 bits') | |
if(value < 0) throw new Error('no support for negative numbers') | |
if(Math.floor(value) !== value) throw new Error('no support for decimal numbers (lol)') | |
if(value >= (2**mbits-1)*2**(2**ebits-1)) return 2**(mbits+ebits)-1 | |
const bitstr = value.toString(2) | |
const len = bitstr.length | |
let m = parseInt(bitstr.substr(0, mbits), 2) | |
let e = Math.min(2**ebits-1, Math.max(0, len - mbits)) | |
if( (m < 2**mbits-1 || e < 2**ebits-1) && Math.abs(value - (m+1)*2**e) < Math.abs(value - m*2**e)) m++ | |
if(m > 2**mbits-1) {m /= 2; e++} | |
return parseInt(m.toString(2).padStart(mbits, 0) + e.toString(2).padStart(ebits, 0), 2) | |
} | |
function frommyfloat(mbits, ebits, value) { | |
const m = (value & ((2**mbits-1) << ebits)) >> ebits | |
const e = value & 2**ebits-1 | |
return m*2**e | |
} | |
// create an 8 bit number that can represent values from 0 to 15032385536 | |
for(const target of [256, 12345, 1000000000000000000]) { | |
const mbits = 3 | |
const ebits = 5 | |
const bits = tomyfloat(mbits, ebits, target) | |
const value = frommyfloat(mbits, ebits, bits) | |
console.log('target value:', target) | |
console.log('actual value:', value, {m:(bits & ((2**mbits-1) << ebits)) >> ebits, e:bits & 2**ebits-1, bits:bits.toString(2)}) | |
} | |
// copy paste into browser console for demo |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment