发生的各种类型转换由JLS #5.6.2指定。在您的情况下(摘录):
- 如果任一操作数是 double 类型,则另一个操作数将转换为 double。
- 否则,如果任一操作数的类型为浮点型,则另一个将转换为浮点型。
在0.0410f * 123456789010d = 506172848.9223363
,0.0410f
中首先转换为不一定等于 的双精度数0.0410d
。其实你可以试试看,不是:
double d1 = 0.041d;
double d2 = 0.041f;
System.out.println(new BigDecimal(d1));
System.out.println(new BigDecimal(d2));
输出:
0.0410000000000000001720845688168992637656629085540771484375
0.041000001132488250732421875
在您的下一个示例中:
0.0410f * 123456789010L = 506172832
long 转换为浮点数,您可以通过以下示例进行验证:
float f1 = 0.0410f;
float f2 = 123456789010L;
System.out.println(new BigDecimal(f1)); // 0.041000001132488250732421875
System.out.println(new BigDecimal(f2)); // 123456790528
System.out.println(new BigDecimal(0.0410f * 123456789010L)); // 5061728768
System.out.println(new BigDecimal(f1 * f2)); // 5061728768
至于一般浮点/双精度操作的精度,请查看这个问题。
最后,如果你使用 BigDecimal,你会得到正确的答案:
BigDecimal a = new BigDecimal("0.041");
BigDecimal b = new BigDecimal("123456789010");
System.out.println(a.multiply(b)); // outputs 5061728349.410