0

有没有一种快速取浮点数模数的方法?

对于整数,梅森素数有一些技巧,因此可以计算 y = x MOD 2^31-1 而无需除法。 整数技巧

可以对浮点数应用任何类似的技巧吗?

优选地,以一种可以转换为矢量/SIMD 操作,或移动到 GPGPU 代码中的方式。这排除了对浮点数据使用整数计算。

我感兴趣的素数是 2^7-1 和 2^31-1,尽管如果浮点数有更有效的素数,那将是受欢迎的。

该算法的一个预期用途是在将输入浮点数读入算法时计算它们的运行“校验和”。为了避免占用过多的计算能力,我想保持这种轻量级。

显然,类似的技术用于更大的数字,特别是 2^127 - 1。不幸的是,论文中的数学超出了我的范围,我无法弄清楚如何将其转换为更小的素数。
浮点 MOD 2^127 - 1 - HASH127 示例

4

1 回答 1

1

我查看了 djb 的论文,你会更容易,因为 31 位很适合 53 位精度双有效位。假设您的校验和由 Z/(2**31 - 1) 上的一些环运算组成,解决计算 x mod Z/(2**31 - 1); 最后,您可以使用整数算术来找到一个规范的算术,这很慢但不应该经常发生。

基本的归约步骤是将整数 x = y + 2**31 * z 替换为 y + z。djb 使用的技巧是计算 w = (x + L) - L,其中 L 是一个经过精心挑选的大整数,用于以 z = 2**-31 * w 的方式进行舍入。然后计算 y = x - w 并输出 y + z,其幅度最多为 2**32。(如果此操作还不够,我深表歉意;如果是,请发布您的校验和算法。)

L 的选择涉及了解有效数字的精确程度。对于模数 2**31 - 1,我们希望最小精度单位 (ulp) 为 2**31。对于 [1.0, 2.0) 范围内的双精度数,ulp 为 2**-52,因此 L 应为 2**52 * 2**31。如果您使用模数 2**7 - 1 执行此操作,那么您将采用 L = 2**52 * 2**7。正如 djb 指出的那样,这个技巧主要取决于中间结果不是以更高的精度计算的。

于 2010-03-24T23:35:19.703 回答