为什么float在Python/PHP/Javascript和Java/C之间的行为不同#

为什么float在Python/PHP/Javascript和Java/C之间的行为不同#,java,c#,python,floating-point,precision,Java,C#,Python,Floating Point,Precision,10年后,我正在(重新)学习Java,我正在编写简单的代码,以便检查语法和验证简单的行为。 我在玩数字类型,我不明白为什么浮点在Java(以及我后来验证的C#)中的行为与Python(或其他脚本语言,如JavaScript或PHP)不同。 问题是,据我所知,当精度很重要时,浮点数是不可靠的,我想到的一个最简单的例子是求和: float(0.1) + float(0.2) 与预期不同的不是float(0.3),而是float(0.300000000000000004),因为“幕后的取整问题”。

10年后,我正在(重新)学习Java,我正在编写简单的代码,以便检查语法和验证简单的行为。 我在玩数字类型,我不明白为什么浮点在Java(以及我后来验证的C#)中的行为与Python(或其他脚本语言,如JavaScript或PHP)不同。 问题是,据我所知,当精度很重要时,浮点数是不可靠的,我想到的一个最简单的例子是求和:

float(0.1) + float(0.2)
与预期不同的不是
float(0.3)
,而是
float(0.300000000000000004)
,因为“幕后的取整问题”。 因此,在我的虚拟Java代码中,我写道:

float wrongResult = 0.1f + 0.2f;
if (wrongResult != 0.3f) {
    System.out.println("float sucks");
}
else {
    System.out.println("float works");
}

double rightResult = 0.1 + 0.2;
if (rightResult != 0.3) {
    System.out.println("double sucks");
}
else {
    System.out.println("double works");
} 
但产出令人惊讶:

float works
double sucks
这让我抓狂,因为double是64位类型,float只是32位类型,所以我希望得到相反的结果,因为double应该更精确。
所以我最大的难题是:为什么像Python、PHP和Javascript这样的脚本语言的行为方式与像Java和C#这样的编译语言的行为方式不同

脚本语言和Java/C之间没有区别。但是,
float
double
之间存在差异。在脚本语言(至少在Python中)中,
float
的底层类型通常具有64位精度(即Java中的
double
)。因此,对于不同的行为,原因是舍入后最接近的值将不相同,从以下内容可以看出:

fl64(.1) == 0.10000000000000001
fl64(.2) == 0.20000000000000001
fl64(.3) == 0.29999999999999999
fl64(.1) + fl64(.2) == 0.30000000000000004

fl32(.1) == 0.1
fl32(.2) == 0.2
fl32(.3) == 0.30000001
fl32(.1) + fl32(.2) == 0.30000001

因此,对于较低的精度(32位),恰好是
0.1+0.2==0.3
。然而,这不是一个普遍的结果,对于许多其他数字来说,这是不成立的。因此,浮点数的精确精度仍然不可靠。

可能重复NOPE!我的问题完全不同!不太精确的
0.1f+0.2f
可能正好等于不太精确的
0.3f
,这为什么会让您感到惊讶呢?这表明它们都是以相同的方式四舍五入的。那么,为什么在Python、PHP或JavaScript中四舍五入的行为不同呢?
float
的四舍五入行为是事物更加四舍五入,这意味着区别更少。如果您不想这样做,请使用
double