【问题标题】:Why precision lost for double casting in Java?为什么在 Java 中双重转换会丢失精度?
【发布时间】:2015-10-18 18:50:58
【问题描述】:

我很惊讶在 Java 中看到以下差异:

 (double)(int1/int2)  // return 0.0 - precision lost.

 (double)int1/int2    // return 9.3123325E-10 - precision kept.

第一个表达式中的括号使评估失去精度是设计使然吗?

【问题讨论】:

  • 括号做吧。
  • int1int2 的值会很有帮助
  • 您在第一个示例中使用整数数学(然后转换为双精度),在第二个示例中使用双精度数学。这确实是设计使然
  • 不到半分钟5个答案

标签: java


【解决方案1】:

是的,这是设计使然。通过将表达式放在括号中,您正在修改正常优先级,因此int1/int2 将首先执行,并且因为两者都是(可能)整数,所以使用整数除法,这会将结果截断为整数。在第二种情况下,应用正常的优先级,因此 int1 首先被转换为双精度,然后使用浮点除法进行除法。

【讨论】:

    【解决方案2】:

    这是order-of-operations 的问题。括号的优先级高于强制转换,因此您的第一条语句将首先执行括号中的操作 - 它将商转换为 double

    转换的优先级高于除法,因此在您的第二个语句中,转换应用除法操作之前。

    【讨论】:

      【解决方案3】:

      因为括号(double)(int1/int2)首先执行整数除法(包括精度损失),然后将结果转换为double

      (double)int1/int2 执行双除法,因为第一个操作数是 double

      【讨论】:

        【解决方案4】:

        当然。在语句 1 中,您进行除法然后进行转换。在语句 2 中,您首先将 int1 转换为双精度,然后进行除法,将 int2 提升为双精度并保持精度。

        我不想这听起来很刻薄,但语言(和编译器)正在做你要求它做的事情。 :)

        【讨论】:

          【解决方案5】:

          在第一个中,您进行整数除法,然后转换为双精度。由于整数除法会截断任何小数,因此您会丢失答案的小数位,并且将其转换为双精度不会带回该信息。

          在第二个中,您将前一个转换为双倍,然后进行双除法。这会使答案自动成为双精度数,因为它在除法时采用更高精度的单位,并确保您也得到小数位。

          第二个等价于((double) int1) / int2,因为转换的优先级高于/

          【讨论】:

            【解决方案6】:

            我认为这与括号(根据 PEMDAS)导致在强制转换发生之前在括号内进行计算有关,因此,如果除法小于 1,则十进制值为 0。

            例子:

            (双) (3/5) = (双) 0; (因为 Int 不能是 .6)

            但是(双)3/5 -->(双).6

            【讨论】:

              猜你喜欢
              • 2017-01-31
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2011-08-24
              • 1970-01-01
              • 2013-06-17
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多