java - Doogee DG800 Android 手机上的 Math.pow(10,6) = 999999.999999

标签 java double-precision

我知道 Math.pow(10,6) 使用 double 执行计算,这意味着精度不是绝对的。当前版本的 Google 身份 validator 使用以下代码来计算代码:

int codeLength = 6;
....
int code = truncatedHash % (int) Math.pow(10, codeLength);

不幸的是,至少有两部 Android 手机(请参阅 google-authenticator issue 396)计算 999999.9999999,这会导致身份验证代码不正确(不起作用)。

该修复是已知的,它使用整数除法器表,因为计数仅限于 10 个可能的值(请参阅问题中引用的修复)。

问题是:这是应用程序程序员的错还是库程序员的错?应用程序程序员应该期望正确的结果(1000000)还是必须考虑有限的精度?

最佳答案

是的,这是库中的错误,应该报告。

Oracle 的 Math.pow() Javadoc 表示:“如果两个参数都是整数,那么结果恰好等于第一个参数的第二个参数次幂的数学结果(如果该结果实际上可以表示)完全作为 double 值。”

“整数”这个词在这里有特殊的含义。如果 floor(x) == x,则 double x 是一个整数

根据该定义,10.0 是一个“整数”,6.0 也是如此,并且每个小于 2^52 的整数都可以精确地表示为 double 值,因此 Math.pow(10.0, 6.0) 应恰好等于 1000000.0。

关于java - Doogee DG800 Android 手机上的 Math.pow(10,6) = 999999.999999,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25714082/

相关文章:

java - 我不能选择我创建的其他单选按钮?

java - 如何让 JTable 填满整个可用空间?

Java,从 ArrayList 中删除对象重写为文本文件

c++ - matlab和c++精度

c++ - std::uniform_real_distribution<double>(0,1) 能否返回大于 0.99999999999999994 的值?

java - Rest Web 服务精确返回 double

java - 如何对 "toString()"GWT EntityProxy derivatives进行日志记录和调试?

java - java 8 中 anyMatch 和 findAny 的区别

CUDA double 和每个线程的寄存器数量

c++ - Matlab 和 c++ 矩阵乘积 : same input, 不同的输出