Java 减去两个十进制数得到奇怪的输出
当我在玩Java拼图游戏时(我没有这本书),我偶然发现了这段代码Java 减去两个十进制数得到奇怪的输出,java,floating-point,Java,Floating Point,当我在玩Java拼图游戏时(我没有这本书),我偶然发现了这段代码 public static void main(String args[]) { System.out.println(2.00 - 1.10); } 输出为 public static void main(String args[]) { System.out.println(2.00 - 1.10); } 0.8999999999999999 当我尝试将代码更改为 publ
public static void main(String args[]) {
System.out.println(2.00 - 1.10);
}
输出为
public static void main(String args[]) {
System.out.println(2.00 - 1.10);
}
0.8999999999999999
当我尝试将代码更改为
public static void main(String args[]) {
System.out.println(2.00 - 1.10);
}
2.00d-1.10d
我仍然得到与0.8999999999999
public static void main(String args[]) {
System.out.println(2.00 - 1.10);
}
对于,2.00d-1.10f
输出为0.899997961581421
对于,
2.00f-1.10d
输出为0.89999999999
对于,
2.00f-1.10f
输出为0.9
public static void main(String args[]) {
System.out.println(2.00 - 1.10);
}
为什么我不能首先将输出设置为
0.9
?我对这件事一无所知?有人能清楚地表达这一点吗?因为在Java中,双值是
public static void main(String args[]) {
System.out.println(2.00 - 1.10);
}
周围的工作可能是使用
public static void main(String args[]) {
System.out.println(2.00 - 1.10);
}
不可变、任意精度有符号十进制数。大小数
由一个任意精度的整数无标度值和一个32位
整数刻度。如果为零或正,则刻度为位数
在小数点的右边。如果为负值,则为的未标度值
这个数字乘以10,等于
规模BigDecimal表示的数字的值为
因此(无标度值×10^-标度)
public static void main(String args[]) {
System.out.println(2.00 - 1.10);
}
在旁注中您可能还需要检查大多数系统中浮点数的存储方式
public static void main(String args[]) {
System.out.println(2.00 - 1.10);
}
对浮点数执行的操作越多,舍入误差就越大。二进制0.1中的为0.00011001
public static void main(String args[]) {
System.out.println(2.00 - 1.10);
}
因此,它不能用二进制精确表示。根据四舍五入(浮动或双精度)的不同位置,您会得到不同的答案
public static void main(String args[]) {
System.out.println(2.00 - 1.10);
}
So 0.1f=0.00011001100
和0.1d=0.00011001
public static void main(String args[]) {
System.out.println(2.00 - 1.10);
}
您注意到该数字在1100个周期内重复。但是,浮点和双精度在循环中的不同点将其拆分。因此,一个错误向上舍入,另一个向下舍入;导致差异
public static void main(String args[]) {
System.out.println(2.00 - 1.10);
}
但最重要的是;
永远不要假设浮点数是精确的其他答案是正确的,只需指向一个有效的引用,我引用:
public static void main(String args[]) {
System.out.println(2.00 - 1.10);
}
double:double数据类型是双精度64位IEEE 754
浮点数。其值的范围超出了本文的范围
讨论,但在浮点类型、格式和
Java语言规范的值部分。对于十进制值,
此数据类型通常是默认选择。如上所述,
此数据类型不应用于精确值,例如
货币
public static void main(String args[]) {
System.out.println(2.00 - 1.10);
}
尝试用二进制表示0.1;读“永远不要相信浮点数是精确的”是不可能的。正确的建议是理解浮点运算,并谨慎使用和设计。IEEE 754标准对浮点运算有很好的规定,只要有适当的知识和谨慎,浮点运算可以用于精确计算。@Eric我想看一个(非人为的)例子,说明假设浮点数是精确的是明智的?@Eric和while“阅读文档”总是很好的建议,它几乎从未被遵循。例如,在函数中,许多操作都是精确的,对于精确的某个定义,所有操作都是“精确的”,并且应该明智地假设它们分别是精确的和精确的,以便算法工作。@Pascal我编辑了我的答案,因为erics发表了意见,但我站在后面永远不要假设浮点数是精确的。BigDecimal不是一个包罗万象的解决方案。它没有提供正确的答案来计算给定年利率的月利息,转换货币,或计算三对一价格交易的单价。@EricPostPhischil:-是的,我知道你想说什么。我刚刚试着让OP意识到这有一些解决办法。这就是我写“解决办法可能是”的原因。我读了一篇有趣的文章:您引用的Oracle文档不正确。浮点运算由IEEE 754标准明确规定,在具备适当知识和谨慎的情况下,可用于精确计算。注意适当和谨慎地详细说明术语
?阅读IEEE 754标准和文本,如,和/或参加数值分析课程。在编写软件时,使用这些知识来评估可能发生的错误的界限和/或了解如何避免这些错误造成的问题(例如,编写容忍这些错误的软件,甚至利用这些错误的软件)。这样做是不准确的,你只是声称程序员可以处理这个负担。如果软件是用于任何重要用途的,程序员不应该编写超出他们能力范围的软件。