Skip to content

Instantly share code, notes, and snippets.

@gcmcom
Forked from Jozo132/float32encoding.js
Created December 25, 2020 09:53
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gcmcom/c189735adc9e0345fc471a618973e9fa to your computer and use it in GitHub Desktop.
Save gcmcom/c189735adc9e0345fc471a618973e9fa to your computer and use it in GitHub Desktop.
JavaScript (Node.js) IEEE 754 Single precision Floating-Point (32-bit) binary conversion from and to both Hex and Bin
// Forked 'toFloat' from https://gist.github.com/laerciobernardo/498f7ba1c269208799498ea8805d8c30
// Forked 'toHex' from stackoverflow answer https://stackoverflow.com/a/47187116/10522253
// Modifyed by: Jozo132 (https://github.com/Jozo132)
const Float32ToHex = (float32) => {
const getHex = i => ('00' + i.toString(16)).slice(-2);
var view = new DataView(new ArrayBuffer(4))
view.setFloat32(0, float32);
return Array.apply(null, { length: 4 }).map((_, i) => getHex(view.getUint8(i))).join('');
}
const Float32ToBin = (float32) => {
const HexToBin = hex => (parseInt(hex, 16).toString(2)).padStart(32, '0');
const getHex = i => ('00' + i.toString(16)).slice(-2);
var view = new DataView(new ArrayBuffer(4))
view.setFloat32(0, float32);
return HexToBin(Array.apply(null, { length: 4 }).map((_, i) => getHex(view.getUint8(i))).join(''));
}
const HexToFloat32 = (str) => {
var int = parseInt(str, 16);
if (int > 0 || int < 0) {
var sign = (int >>> 31) ? -1 : 1;
var exp = (int >>> 23 & 0xff) - 127;
var mantissa = ((int & 0x7fffff) + 0x800000).toString(2);
var float32 = 0
for (i = 0; i < mantissa.length; i += 1) { float32 += parseInt(mantissa[i]) ? Math.pow(2, exp) : 0; exp-- }
return float32 * sign;
} else return 0
}
const BinToFloat32 = (str) => {
var int = parseInt(str, 2);
if (int > 0 || int < 0) {
var sign = (int >>> 31) ? -1 : 1;
var exp = (int >>> 23 & 0xff) - 127;
var mantissa = ((int & 0x7fffff) + 0x800000).toString(2);
var float32 = 0
for (i = 0; i < mantissa.length; i += 1) { float32 += parseInt(mantissa[i]) ? Math.pow(2, exp) : 0; exp-- }
return float32 * sign;
} else return 0
}
// Full example
var test_value = -0.3;
console.log(`Input value (${test_value}) => hex (${Float32ToHex(test_value)}) [${Math.ceil(Float32ToHex(test_value).length / 2)} bytes] => float32 (${HexToFloat32(Float32ToHex(test_value))})`);
console.log(`Input value (${test_value}) => binary (${Float32ToBin(test_value)}) [${Float32ToBin(test_value).length} bits] => float32 (${BinToFloat32(Float32ToBin(test_value))})`);
/* DEBUG OUTPUT:
Input value (-0.3) => hex (be99999a) [4 bytes] => float32 (-0.30000001192092896)
Input value (-0.3) => binary (10111110100110011001100110011010) [32 bits] => float32 (-0.30000001192092896)
*/
// Forked 'toFloat' from https://gist.github.com/laerciobernardo/498f7ba1c269208799498ea8805d8c30
// Forked 'toHex' from stackoverflow answer https://stackoverflow.com/a/47187116/10522253
// Modifyed by: Jozo132 (https://github.com/Jozo132)
const Float32ToHex = float32 => { const getHex = i => ('00' + i.toString(16)).slice(-2); var view = new DataView(new ArrayBuffer(4)); view.setFloat32(0, float32); return Array.apply(null, { length: 4 }).map((_, i) => getHex(view.getUint8(i))).join(''); }
const Float32ToBin = float32 => parseInt(Float32ToHex(float32), 16).toString(2).padStart(32, '0');
const ToFloat32 = num => { if (num > 0 || num < 0) { var sign = (num >>> 31) ? -1 : 1; var exp = (num >>> 23 & 0xff) - 127; var mantissa = ((num & 0x7fffff) + 0x800000).toString(2); var float32 = 0; for (i = 0; i < mantissa.length; i += 1) { float32 += parseInt(mantissa[i]) ? Math.pow(2, exp) : 0; exp-- } return float32 * sign; } else return 0 }
const HexToFloat32 = str => ToFloat32(parseInt(str, 16));
const BinToFloat32 = str => ToFloat32(parseInt(str, 2));
// ------ FULL EXAMPLE ------
var value = -0.3; // JS number variable
// FLOAT32 <===> HEX
var f32_hex = Float32ToHex(value); // JS number => HEX string of a Float32 standard number
var f32_hex_inverse = HexToFloat32(f32_hex); // HEX string of a Float32 standard number => JS number
// FLOAT32 <===> BIN
var f32_bin = Float32ToBin(value); // JS number => HEX string of a Float32 standard number
var f32_bin_inverse = BinToFloat32(f32_bin); // HEX string of a Float32 standard number => JS number
console.log(`Input value (${value}) => hex (${f32_hex}) [${Math.ceil(f32_hex.length / 2)} bytes] => float32 (${f32_bin_inverse})`);
console.log(`Input value (${value}) => binary (${f32_bin}) [${f32_bin.length} bits] => float32 (${f32_bin_inverse})`);
/* DEBUG OUTPUT:
Input value (-0.3) => hex (be99999a) [4 bytes] => float32 (-0.30000001192092896)
Input value (-0.3) => binary (10111110100110011001100110011010) [32 bits] => float32 (-0.30000001192092896)
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment