如何使用Node.js将64位浮点截断为32位截断浮点并返回(丢弃精度)



很明显,没有32位浮点值,但如果我们试图有效地存储大数据,并且我们的许多值都是不大于100000的浮点值,正好有两个小数点,那么通过删除表示我们不需要的精度的位,将64位值存储在32位中是有意义的。

我试着这样做,只需像这样写入64位BE浮点缓冲区,并对前4个字节进行切片:

// float32 = Number between 0.00 and 100000.00
const setFloat32 = (float32) => {
b64.writeDoubleBE(float32, 0) // b64 = 64 bit buffer
b32 = b64.slice(0, 4)
return b32;
}

通过添加4个空字节读取:

// b32 = the 32 bit buffer from the previous func
const readFloat32 = (b32) => {
// b32Empty = empty 32 bit buffer
return Buffer.concat([b32, b32Empty]).readDoubleBE(0);
}

但这种修改后的平面小数类似于:

1.85 => 1.8499994277954102
2.05 => 2.049999237060547

如何修改我的方法以正确地做到这一点,并以最有效的方式提高阅读速度?

如果您只想保留两位小数的精度,您可以将您的值转换为移位整数并存储:

function shiftToInteger(val, places) {
// multiply by a constant to shift the decimals you want to keep into
// integer positions, then use Math.round() or Math.floor()
// to truncate the rest of the decimals - depending upon which behavior you want
// then return the shifted integer that will fit into a U32 for storage
return Math.round(val * (10 ** places));   
}

这将创建一个移位的整数,然后可以将其存储在32位值中(具有您所描述的值限制(,例如Uint32ArrayInt32Array。要在从存储中检索时使用它,您需要将它除以100,将其转换回标准的Javascript浮点值以供使用。

关键是将您想要保持的小数精度转换为整数,这样您就可以将其存储在一个非浮点类型的值中,该值刚好足够您的最大预期值。您可以提高存储效率,因为您将所有存储位用于所需的精度,而不是在不需要保留的十进制精度上浪费大量不必要的存储位。

这里有一个例子:

function shiftToInteger(val, places) {
return Math.round(val * (10 ** places));   
}
function shiftToFloat(integer, places) {
return integer / (10 ** places);
}

let x = new Uint32Array(10);
x[0] = shiftToInteger(1.85, 2);
console.log(x[0]);                   // output shifted integer value
console.log(shiftToFloat(x[0], 2));  // convert back to decimal value

最新更新