To start, I am in the wrong language and I think it is time learn some C++ and compile it as an add-on for NodeJS. For now, though, I have a few code snippets that work that may be interesting or may be an abomination of coding.
This code works with weather forecast data, specifically the GRIB-2 file format. GRIB-2 compresses weather information into either integers or floating point values depending on the type (this cast is wind gusts). The data has been packed into 8-bit floating point values. I am assuming the GRIB-2 protocol follows floating point arithmetic and we can break our 8-bits into the following sections: 0 000 0000
Code to convert hex: 26 to floating-point: 0.6875:
var bin = makeWhole('100110'); //hex: 26
var fp = nBitFloatPoint(8, bin); //8 is unused but will allow different bit lengths
console.log(fp) // 0.6875
function makeWhole(a){
var hex = a;
if(hex.length !== 8){
hex = prepend(hex);
}
return hex;
}
function prepend(hex){
var diff = 8 - hex.length;
var str = '';
for(var i=0; i<diff; i++){
str += '0';
}
return str + hex;
}
function nBitFloatPoint(n, bin){
var s = bin.charAt(0);
var e = parseInt(bin.substring(1, 4), 2) - 3;
var m = '1.' + bin.substring(4, 8);
var d = shiftDot(m, e);
var result = convert(s, e, d);
return result;
}
function convert(s, e, d){
var strD = d.toString()
var length, dotIndex, num, frac;
var values = [];
length = strD.length;
dotIndex = strD.indexOf('.');
num = strD.substring(0, dotIndex).split('');
frac = strD.substring(dotIndex + 1).split('');
//console.log(num)
for(var i=0; i<num.length; i++){
if(parseInt(num[i])){
values.push(Math.pow(2, i));
}
}
for(var i=0; i<frac.length; i++){
console.log(frac)
if(parseInt(frac[i])){
//console.log(Math.pow(2, -i))
values.push(Math.pow(2, -i-1));
}
}
if(values.length){
return values.reduce(arraySum);
}
return 0;
}
function arraySum(prev, curr, index, arr){
return prev + curr;
}
function shiftDot(m, e){
var str = '00000000000000000000000000' + m;
var dot = str.indexOf('.');
str = str.replace('.', '');
return parseFloat(str.substring(0, dot + e) + '.' + str.substring(dot + e));
}
Is this a really hack idea that is best left to a language mean to work with binary buffers? Is the function shiftDot
a plausible workaround or am I missing something best left to an internal JS function?
122
from0x26
. \$\endgroup\$GRIB
) does not state how it is split but I know that in this example there must be a decimal because wind speeds of122 m/s
or272 mph
isn't feasible at sea-level. I was basing my conversion off this post \$\endgroup\$makeWhole(0x26)
returns 38. The number 38. Not a string, and certainly not a binary string. So everything from that point on will only make it things worse. It's quite surprising it actually returns anything resembling a float at the end. \$\endgroup\$