将浮点值分配给双精度值
Posted
技术标签:
【中文标题】将浮点值分配给双精度值【英文标题】:Assigning floating value to a double value 【发布时间】:2014-02-19 09:19:26 【问题描述】:我指的是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
为什么第二行输出显示的是近似值。但不适用于第四行。 值是如何计算的?
【问题讨论】:
顺便说一句1.1f
是 float
文字,将其分配给 double 可能会产生误导。
第一个只是没有告诉你它具有相同的近似值floating-point-gui.de
df
实际上是这个1.500000000000000
,零被跳过了
有关浮点表示的更多信息,请参阅 ieee 754 标准
您的问题实际上是关于将单精度值打印作为双精度值。简而言之,Java 只打印足够的数字,以便准确地确定单精度或双精度值。当您将1.1f
打印为double
时,该类型具有更高的精度,因此需要更多的数字来明确double
的含义。见***.com/questions/916081/…
【参考方案1】:
不同之处在于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.1f(不是 1.1)。不应该是同一个常数吗? @starmole 将1.1f
分配给double
会导致比可能的数字更不准确,即,当打印为双精度数字时,它是如此不准确,以至于它在打印时打印 000023.. 部分因为float
直接跳过打印该不准确之处,因为它知道打印数字超过某个点没有更多价值。如果您将 1.1
分配为 double,您将在数量级上更接近 1.1,因为您可以使用更多位。那将打印为“1.1”。
@starmole:Java 打印浮点的默认设置是打印足够的数字来唯一标识其类型中的值。在float
中,“1.1”就足够了,因为1.1f
(正好是 1.10000002384185791015625)比任何其他float
更接近 1.1。在double
,“1.1”是不够的,因为double
1.100000000000000088817841970012523233890533447265625更接近1.1比1.10000002384185791015625是,那么你需要更多的数字更贴近的1.10000002384185791015625值。 SPAN>
【参考方案2】:
示例
在处理小数位时考虑二进制,更重要的是考虑二进制。
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
,并且二进制文件会尽可能接近。
【讨论】:
【参考方案3】:是的,我们知道,一个数字在 double 中的表示比在 float 中的相同。浮点数以 32 位表示,而双精度数以 64 位表示。因此,当将浮点数分配给双精度时,数字将从 32 位扩展到 64 位。然后以准确的方式表示不准确的数字。那么,你是不是更明白这一点了?
【讨论】:
以上是关于将浮点值分配给双精度值的主要内容,如果未能解决你的问题,请参考以下文章
如何将浮点值转换为具有精确精度的整数,例如 123.3443 到 1233443?