【问题标题】: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 的含义。见stackoverflow.com/questions/916081/…

标签: java floating-point double


【解决方案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 位。然后以准确的方式表示不准确的数字。那么,你是不是更明白这一点了?

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-11-07
      • 2010-09-27
      • 1970-01-01
      • 1970-01-01
      • 2022-11-19
      • 2011-05-17
      • 2015-08-30
      • 1970-01-01
      相关资源
      最近更新 更多