我指的是this Oracle文档。在尝试执行以下操作时,
public static void main(String args[]){
float f = 1.1f;
double df = 1.1f;
System.out.println("f=" + f);
System.out.println("df=" + df);
f = 1.5f;
df = 1.5f;
System.out.println("f=" + f);
System.out.println("df=" + df);
}
输出
f = 1.1
df = 1.100000023841858
f = 1.5
df = 1.5
为什么第二行输出显示近似值。但不是第四线。 如何计算价值?
答案 0 :(得分:4)
不同之处在于1.5
可以完全用双精度表示 - 而1.1
无法准确表示。
这是因为周期性数字,任何(不可简化的)分数,其中分母具有不在基数中出现的素因子,需要在某个点之后周期性重复的无限数量的数字。例如,在十进制1/4
中,3/5
和8/20
是有限的,因为2
和5
是10
的主要因素。但1/3
不是有限的,也不是2/3
或1/7
或5/6
,因为3
和7
不是10
的因素}。分母中具有5
的素因子的分数在基数10
中可以是有限的,但在基数2
中则不是 - 对于大多数浮点数新手用户而言,这是最大的混淆源。
将无数多个实数压缩成有限数量的位 需要近似的表示。虽然有无限的 许多整数,在大多数程序中,整数计算的结果都可以 以32位存储。相反,给定任意数量的位, 大多数带有实数的计算都会产生数量 不能使用那么多位来精确表示。因此 浮点计算的结果通常必须按顺序舍入 以适应其有限的表示。这个舍入误差是 浮点计算的特征。
查看here了解详情
答案 1 :(得分:3)
实施例
在处理小数位时考虑二进制,更重要的是二进制。
4 2 1 . 1/2 1/4 1/8
0 0 1 . 1 0 0
因此,正如您所看到的,计算机可以毫无问题地表示这一点。现在让我们看一下1.1
。
4 2 1 . 1/2 1/4 1/8 1/16
0 0 1 . 0 0 0 1
目前,我们有1.0625
。正如您可以想象的那样,确切地获得0.0475
有点困难,但我们可以继续尝试以示例:
4 2 1 . 1/2 1/4 1/8 1/16 1/32 1/64 1/128
0 0 1 . 0 0 0 1 1 0 0
现在我们需要1.8
,所以让我们继续......
4 2 1 . 1/2 1/4 1/8 1/16 1/32 1/64 1/128
0 0 1 . 0 0 0 1 1 1 0
我们已经0.915625
..
4 2 1 . 1/2 1/4 1/8 1/16 1/32 1/64 1/128
0 0 1 . 0 0 0 1 1 1 1
我们在0.9234375
。
说明
我确定你能看到我的目标。您想要表示的数字与二进制可以表示的数字之间始终存在错误。有时候,你很幸运,比如1.5
,二进制代表没有问题。其他时候,您遇到了问题,例如1.1
,二元版本尽可能接近。
答案 2 :(得分:0)
是的,正如我们所知,double中的数字表示比float中的数字更准确。浮点数用32位表示,而double用64位表示。因此,当float被赋值为double时,数字从32位扩展到64位。然后以准确的方式表示不准确的数字。所以,你更了解这一点吗?