使用FLOAT进行乘法运算会产生明显的差异。
public static void main(String[] args) {
// using string and parsing instead of actual data type is part of use case, that is why representing the same here
double v1 = parseDouble("590.0");
double v2 = parseDouble("490.0");
double v3 = parseDouble("391.0");
float v4 = parseFloat("590.0");
float v5 = parseFloat("490.0");
float v6 = parseFloat("391.0");
System.out.println(new BigDecimal(v1 * v2 * v3));
System.out.println(new BigDecimal(v4 * v5 * v6));
System.out.println(BigDecimal.valueOf(Float.parseFloat("289100.0") * Float.parseFloat("391.0")));
System.out.println(BigDecimal.valueOf(Double.parseDouble("289100.0") * Double.parseDouble("391.0")));
}
输出:
113038100 // double multiplication
113038096 // float multiplication
113038096
113038100
对于上述代码,
(590.0 * 490.0 * 391.0)使用双精度浮点数得到113038100
(590.0 * 490.0 * 391.0)使用浮点数得出113038096(113038100 - 113038096 = 4//差值)
我已经阅读了https://floating-point-gui.de/basic/这个链接,并能够理解如何浮点计算发生,但所有4计数不同是意想不到的。
请帮助我了解以下事项
- 这是正确的第一
- 浮动总是给出错误的数字吗?
- 正如我所看到的,双精度也使用相同的技术,那么,如果我们使用双精度,我们有多少保证得到正确的结果呢
2条答案
按热度按时间qojgxg4l1#
浮动总是给出错误的数字吗?
这取决于数字,如果数字可以用浮点精度表示,那么就可以了
正如我所看到的,双精度也使用相同的技术,那么如果我们使用双精度,我们有多少保证可以得到正确的结果呢?
double也有同样的问题,但由于double的精度更高,因此可能性更低,但仍会发生
因此,当你需要一个非常精确的结果,如在科学或金融应用程序,你将需要使用BigDecimal
观看此视频,它解释如何浮点数工作https://www.youtube.com/watch?v=ajaHQ9S4uTA
eeq64g8w2#
这是正确的第一
Java
float
是IEEE-754 binary32。在这种格式中,每个有限数都表示为一个符号、一个24位整数和一个2的幂(从2 − 149到2104)。整数部分称为有效位。(格式通常被描述为符号,一个24位数,在第一位之后有一个二进制小数点,所以它的值在[0,2]中),和从2 − 126到2127的缩放比例。它们在数学上是等价的,这里使用的格式在IEEE-754标准中作为一个选项注明。)在正规形式中,24位整数是223或更大。(小于2 − 126的可表示数不能用正规形式表示,必须是次正规的。)在这种格式下,590可以表示为+590 20或+8,339,456 2 − 14。
它们的乘积为+289,100 20或+9,251,200 2 − 5。
391等于+391 20或+12,812,288 15。
+289,100 20和+391 20的普通算术乘积是+113,038,100 20。然而,113,038,100不是一个24位数;它是一个27位数,要使它小于224,我们可以调整缩放比例,将有效位乘以,缩放比例乘以8 = 23。
这就是+14,129,762.5 23。然而,现在的有效位不是整数。这个结果不能用
float
表示。为了产生一个结果,float
的加法运算被定义为将普通算术舍入到最近的可表示值。在这种情况下,有一个平局。我们可以将0.5向上或向下舍入,平局通过舍入使低位数为偶数来解决,因此我们舍入到+14,129,762 23。+14,129,762 23等于113,038,096,这就是你得出的结果,所以是正确的。
浮动总是给出错误的数字吗?
这并没有错;这台计算机按照它的规格运行。
注意,
float
是一个32位格式,但是有无穷多个实数,甚至有无穷多个有理数,32位格式不可能产生与理论实数算术或有理数算术相同的结果,可能的结果比可表示的值多。64位
double
也是如此,整数格式、固定精度格式和所有具有固定位数的数值格式也是如此,固定位数不能表示无限多的值。您的评论表明,您认为浮点数对于小数值(小于1的数字)会产生近似结果。但是,对于可以表示多少个值的限制适用于所有尺度。(2的每一次幂),只有224个值是可表示的(标准形式的223)。对于标度20,所有小于224的非负整数都是可表示的。但是,大于224的整数只有一些是可表示的。起初,我们必须跳过第二个整数,然后是第四个整数,然后是第八个整数,依此类推。
浮点运算是为近似实数运算而设计的。当您希望近似实数运算时,应使用浮点运算。当您希望精确运算时,不应使用浮点运算,只有极少数例外。