双数据类型的奇怪行为

Posted

技术标签:

【中文标题】双数据类型的奇怪行为【英文标题】:Strange behavior of double data type 【发布时间】:2014-03-31 08:08:38 【问题描述】:

我的代码如下:

Number inputAmount = NumberFormat.getNumberInstance(Locale.FRANCE).parse("7,10");
double doubleValue = inputAmount.doubleValue();
int intValue = (int) (doubleValue * 100);

System.out.println("Input: " + inputAmount);
System.out.println("Double: " + doubleValue);
System.out.println("Integer: " + intValue);

哪个输出:

Input: 7.1
Double: 7.1
Integer: 710

但是,当inputValue 为 5,10 时,输出为:

Input: 5.1
Double: 5.1
Integer: 509

这只发生在 5,10 和 4,10 上。我知道它是由于双精度而发生的,但我不知道到底是怎么回事。 有什么想法吗?

【问题讨论】:

看起来 4 和 5 不能像 7 那样精确表示.. 是的,我在遇到这个问题后使用了 BigDecimal,并且解决了它,但我想知道为什么第一种方法不起作用。 【参考方案1】:

这里的问题是,乘法 5.1d * 100d 会产生舍入误差,从而导致 509.99999999999994d。而当你把这个double转换成一个整数时,结果显然是509

要了解这里发生了什么,请考虑以下几点:

double doubleValue = 5.1d * 100d; // rounding error...
System.out.println("Double: " + doubleValue);
int intValue = (int) doubleValue;
System.out.println("Integer: " + intValue);

输出:

Double: 509.99999999999994
Integer: 509

【讨论】:

奇怪的是它只发生在 5.10 和 4.10 的值上。【参考方案2】:

尝试改变:

int intValue = (int) (doubleValue * 100);

到:

int intValue = (int) (doubleValue * 100d);

您的代码已经相当简化了,我想当它成倍增加时,内部转换可能会发生一些奇怪的事情。 100d 将强制它在最终转换为 int 之前乘以两个双精度值。

【讨论】:

以上是关于双数据类型的奇怪行为的主要内容,如果未能解决你的问题,请参考以下文章

矩阵形成中的奇怪行为(C++,犰狳)

使用 HSQLDB 关键字的奇怪行为

MPI 派生数据类型适用于浮点数,但不适用于双精度数。是对齐问题吗?

递归泛型类型来扩展类型 - 奇怪的行为,这是一个错误吗?

boost::variant:递归向量类型的奇怪行为

PyCharm 中类型提示 dict.items() 时的奇怪行为