【问题标题】:Precise division of doubles representing integers exactly (when they are divisible)精确表示整数的双精度除法(当它们可整除时)
【发布时间】:2014-04-21 07:43:48
【问题描述】:

鉴于8-byte doubles can represent all 4-byte ints precisely,我想知道是否将存储 int 的 double A 除以存储 int 的 double B(使得整数 B 除以 A)将始终给出与整数对应的精确 double他们的商?因此,如果 B 和 C 是整数,并且 B*C 适合 32 位 int,则可以保证

int B,C = whatever s.t. B*C does not overflow 32-bit int
double(B*C)/double(C) == double((B*C)/C) ?

IEEE754 标准是否保证这一点?

在我的测试中,它似乎适用于我尝试过的所有示例。在 Python 中:

>>> (321312321.0*3434343.0)/321312321.0 == 3434343.0
True

问的原因是 Matlab 很难处理整数,所以我经常只使用默认的双精度数进行整数计算。当我知道整数是完全可整除的,并且如果我知道当前问题的答案是肯定的,那么我可以避免对整数进行强制转换,idivide(..) 等,这样可读性较差。

【问题讨论】:

标签: matlab division ieee-754 integer-division double-precision


【解决方案1】:

Luis Mendo 的评论确实回答了这个问题,但为了专门解决在 Matlab 中的使用,有一些方便的实用程序 described here。您可以使用eps(numberOfInterest) 查找到下一个最大双精度浮点数的距离。例如:

eps(1) = 2^(-52)
eps(2^52) = 1

这实际上保证了使用双精度整数的数学运算将是精确的,前提是它们不会溢出 2^52,这比 32 位 int 类型中的整数大很多。

【讨论】:

  • 那么,对双精度数的运算结果是否保证是实际结果的最近双精度数?我的印象是 Java 的 StrictMath 是针对 docs.oracle.com/javase/7/docs/api/java/lang/StrictMath.html 的,而普通(快速和准确之间的权衡)操作可能会导致最后一两位二进制数字中的微小错误。
  • 我不熟悉 Java 或 StrictMath,但我阅读文档时说“严格”是指“[StrictMath 中的算法] 产生与......已发布的算法相同的结果...... .来自著名的...包... fdlibm”。也就是说,StrictMath 方法保证您将获得与使用 fdlibm 方法获得的结果相同的结果。毫无疑问,用于数学函数的算法具有快速且不太准确或较慢且更精确的风格。但是,除非我弄错了,除法只有一种算法,所以这个问题在这里不适用。
  • 对于它的价值,The Mathworks 通常对他们在每个 Matlab 函数中使用的算法是透明的(参见文档)。因此,如果您对某个特定的数学函数感兴趣,您应该能够更仔细地探索它。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-10-20
  • 1970-01-01
  • 2011-03-09
  • 1970-01-01
  • 1970-01-01
  • 2013-03-16
  • 2016-11-06
相关资源
最近更新 更多