我试图在Java中更多地了解浮点数、双小数和双小数。我想知道浮点数在每种类型中是如何表示的,比如ex。浮点数使用2^,大小数使用10^加号(32位)和非缩放值(任意精度).
我把所有三种类型的简单计算组合在一起,并对每一种类型进行对话,结果是相当混乱的。我希望得到一些提示,说明为什么惟一正确的表示形式是用于浮点,以及为什么当转换为Double和BigDecimal时会出现不精确。它与二进制表示转换有关吗?总之,这里是代码及其输出:
// Float - 32b
float a = 3.14f;
float b = 3.100004f;
float abAsAFloat = a + b;
double abAsADouble = a + b;
BigDecimal abAsABigDecimal = new BigDecimal(a + b);
System.out.println("a + b as a float: " + abAsAFloat);
System.out.println("a + b as a double: " + abAsADouble);
System.out.println("a + b as a BigDecimal: " + abAsABigDecimal);
// Double - 64b
double c = 3.14;
double d = 3.100004;
double cdAsADouble = c + d;
BigDecimal cdAsABigDecimal = new BigDecimal(c + d);
System.out.println("c + d as a double: " + cdAsADouble);
System.out.println("c + d as a BigDecimal: " + cdAsABigDecimal);
// BigDecimal, arbitrary-precision, signBit*unscaledValue × 10^-scale
BigDecimal e = new BigDecimal(3.14);
BigDecimal f = new BigDecimal(3.100004);
BigDecimal efAsABigDecimal = e.add(f);
System.out.println("e + f: " + efAsABigDecimal);
// Drawbacks. speed, memory, native value equality, no overloads for +/- et alA+b作为浮点数: 6.240004 A+b作为双倍: 6.240004062652588 A+b作为BigDecimal: 6.240004062652587890625 C+d作为双倍: 6.240004000000001 C++d作为一个6.2400040000000007722746886429376900196075439453125 :BigDecimal E+ f: 6.240004000000000328185478792875073850154876708984375
发布于 2015-09-15 20:56:40
对于这种特殊情况,float看起来可能是正确的,但对于其他值来说,它同样是错误的。请注意,当float和double转换为字符串时,只需要打印足够多的数字才能获得该类型的正确值;这意味着float可以打印“正确的答案”,即使表示形式隐藏了与double一样多的舍入错误。
BigDecimal的问题在于您没有正确地使用它:您应该编写new BigDecimal("3.14")而不是new BigDecimal(3.14),这允许double在BigDecimal有机会“修复它”之前“把它搞砸”。
对于表示的细节,格式化用有用的图表作了详尽的解释,但简短的解释是,float和double将数字表示为+/- 1* 1. * 2^,其中float存储尾数22位,指数存储8位,double分别使用52位和11位。
发布于 2015-09-15 20:58:37
你无意中混合了类型。例如:
BigDecimal e = new BigDecimal(3.14);
BigDecimal f = new BigDecimal(3.100004);在这种情况下,您提供双倍作为输入,因此e和f将有双剩余。相反,请使用以下命令:
BigDecimal e = new BigDecimal("3.14");
BigDecimal f = new BigDecimal("3.100004");浮点输出似乎是最精确的,因为Java“知道”浮点数的精度有限,所以它不会打印15位数字。
发布于 2015-09-15 21:01:11
当您转换为double或BigDecimal时,它将转换为最接近可表示的值。当您转换到BigDecimal时,您实际上首先要转换为double,因为没有直接从float进行的转换。
通常,您想要使用double转换为BigDecimal,这个方法假设一定程度的舍入,以匹配如果打印它的话,它看起来会是什么样子。
https://stackoverflow.com/questions/32595351
复制相似问题