Lyd*_*Lyd 2 java printing string math floating-point
据我所知,有些数字不能用二进制精确表示,这就是为什么浮点运算有时会给我们带来意想不到的结果; 像4.35*100 = 434.99999999999994.与十进制中的1/3相似的东西.
这是有道理的,但这引发了另一个问题.似乎在二进制中4.35和435都可以精确表示.那就是它停止对我有意义的时候.为什么4.35*100的评估结果为434.99999999999994?435和4.35在双重类型动态中具有精确表示:
double number1 = 4.35;
double number2 = 435;
double number3 = 100;
System.out.println(number1); // 4.35
System.out.println(number2); // 435.0
System.out.println(number3); // 100.0
// So far so good. Everything ok.
System.out.println(number1 * number3); // 434.99999999999994 !!!
// But 4.35 * 100 evaluates to 434.99999999999994
Run Code Online (Sandbox Code Playgroud)
为什么?
编辑:此问题被标记为重复,但事实并非如此.正如您在接受的答案中所看到的,我的困惑在于实际值与印刷值之间的差异.
Roh*_*ain 12
似乎在二进制中4.35和435都可以精确表示.
我看到你了解浮点数是如何在内部表示的.至于你的疑问,没有4.35没有确切的二进制表示.所以问题是,为什么打印第一个打印语句4.35.
发生这种情况是因为System.out.println()调用了Double.toString(double)方法,而方法又使用FloatingDecimal#toJavaFormatString()方法,该方法在传递的double参数内部执行一些舍入.您可以浏览我链接的源代码.
要查看实际值4.35,请尝试使用:
BigDecimal bd = new BigDecimal(number1);
System.out.println(bd);
Run Code Online (Sandbox Code Playgroud)
这将打印:
4.3499999999999996447286321199499070644378662109375
Run Code Online (Sandbox Code Playgroud)
在这种情况下,您可以创建一个BigDecimal将double值传递为参数的对象,而不是打印double值.BigDecimal表示任意精度带符号十进制数.所以它给你的确切值4.35.
你是对的,有时浮点运算会产生意想不到的结果.
您4.35可以在浮点中精确表示的断言是不正确的,因为它不能表示为终止二进制十进制. 100显然可以准确地表示,因此对于结果434.99999999999994,`4.35不能准确表示.
要准确地用浮点表示,数字必须能够转换为分母,其中分母只有2的幂(并且它必须不能精确到超过浮点类型的最大精度你'正在使用).在这种情况下,4.35是4 7/20,并且分母具有因子5,因此该数字不能精确地以二进制表示.