【问题标题】:How do I properly truncate a 64 bit float to a 32 bit truncated float and back (dropping precision) with Node.js?如何使用 Node.js 正确地将 64 位浮点数截断为 32 位截断浮点数并返回(降低精度)?
【发布时间】:2021-01-25 01:58:55
【问题描述】:

所以显然没有 32 位浮点数,但如果我们要有效地存储大数据并且我们的许多值是不大于 100,000 且恰好有 2 个小数位的浮点数,那么将 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

我怎样才能修正我的方法来正确地做到这一点,并以最有效的方式来提高阅读速度?

【问题讨论】:

    标签: node.js floating-point binary precision


    【解决方案1】:

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

    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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-12-31
      • 2017-05-08
      • 2011-06-07
      • 2019-03-01
      • 1970-01-01
      • 2017-07-04
      相关资源
      最近更新 更多