Skip to content

Instantly share code, notes, and snippets.

@farzher
Last active June 27, 2020 22:43
Show Gist options
  • Save farzher/bd60c58886ca54f6b161f80cf5c5d891 to your computer and use it in GitHub Desktop.
Save farzher/bd60c58886ca54f6b161f80cf5c5d891 to your computer and use it in GitHub Desktop.
floating precision positive whole numbers using arbitrary mantissa / exponent sizes
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