【问题标题】:Best performing way to emulate integer overflow?模拟整数溢出的最佳执行方式?
【发布时间】:2020-09-01 23:32:30
【问题描述】:

我在搞乱哈希函数,移植一些经典,如 murmur 或 fnv 系列,并创建我自己的,真的很有趣。我知道 js 并不是一个理想的环境,但无论如何。

我遇到的最大障碍是 js 对大多数算术都使用双精度数。我见过的几乎每一个散列函数都通过乘法来利用整数溢出。例如,我将 7 的输入乘以 0x5bd1e995 之类的大素数,这种乘法将小输入的重要性放大到结果的每一位,这对于散列函数来说非常简洁。

不幸的是,当使用双精度进行数学运算时,这完全是平的,因为双精度不会像整数那样溢出(保留最低有效位),而是尝试保留结果的大小(保留最高有效位)并且与几乎所有哈希函数的设计。

我发现解决这个问题的几种方法是

  1. 在乘法之前对输入取模,以确保结果不超过 Number.MAX_SAFE_INTEGER
  2. 将输入拆分为两个 16 位值并重新组合后进行乘法运算
  3. 根据输入使用各种幻数,以确保我保持在整数的双精度范围内

问题是,这些都不是快速的,并且会将性能切成碎片。那么,提问时间:如果乘法几乎肯定会超过 Number.MAX_SAFE_INTEGER,是否有一种性能良好的方法来模拟 js 中的整数溢出行为?

【问题讨论】:

  • 你的意思是像c类型的int乘法吗?它只是截断高位并在溢出期间保留低位 32。如果你想看看Math.imul
  • 我猜BigInt 在您的可能但缓慢的选项列表中排名第四?
  • @HanYolo 没错,正在调查!
  • @AhmedFasih 是的,BigInt 在技术上是一种选择,但比其他所有方法加起来都慢。
  • @zero298 问题是,一旦你从一个类型化的数字数组中获取一个值,它就会变成一个普通的 JavaScript 数字。

标签: javascript algorithm integer-overflow


【解决方案1】:

请查看Math.imul

这会将数字乘以 32 位整数并简单地截断溢出位。

【讨论】:

    猜你喜欢
    • 2023-01-03
    • 2011-02-26
    • 1970-01-01
    • 1970-01-01
    • 2011-11-14
    • 2016-11-21
    • 2014-10-01
    • 2018-07-24
    • 2012-01-29
    相关资源
    最近更新 更多