【问题标题】:Type casting in Java. Double to longJava 中的类型转换。双倍到长
【发布时间】:2015-09-19 08:43:00
【问题描述】:

为什么System.out.println((long)Math.pow(2,63));System.out.println((long)(Math.pow(2,63)-1));在Java中的输出是一样的?

【问题讨论】:

    标签: java typecasting-operator


    【解决方案1】:

    输出是相同的,因为double 没有足够的位来准确表示 263

    尾数 double 只有 52 位:

    这为您提供最多 17 位十进制数字的精度。另一方面,您计算的值是 9223372036854775808,因此需要 19 位数字才能准确表示。结果,263的实际表示是9223372036854776000:

    • 尾数设置为 1.0(隐含前面的 1)
    • 指数设置为 1086(隐式减去 1024 得到 63)

    1的表示尾数相同,而指数为1024为有效值0,即两个数的指数相差63,大于尾数的大小。

    当您的号码表示为 double 时,会发生减 1。由于被减数的幅度远大于减数的幅度,所以整个减法运算都被忽略了。

    减去更大的数字后,您会得到相同的结果 - 一直到 512,即 29 (demo)。之后,指数的差异将小于 52,因此您将开始得到不同的结果。

    【讨论】:

      【解决方案2】:

      Math.pow( double, double ) 返回一个double 值。

      double 在 java 中是一个 64 位 IEEE 754 浮点数。(https://docs.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html)

      如果你看这里:https://en.wikipedia.org/wiki/Double-precision_floating-point_format 你会发现,这个格式是由:

      • 1 位符号
      • 11 位指数
      • 53 位有效精度

      pow 返回的数字需要更高的精度 (63) 才能准确存储。

      基本上,您添加的1 低于此精度阈值。

      相比之下,long 的精度为 64 位。

      为了更清楚,假设我们使用十进制而不是base2:

      在精度为2 的一些虚构的小浮点数据类型中,值1000 将存储为1.00e3。如果添加 1,则必须将其存储为 1.001e3。但由于我们只有 2 的精度,它只能存储 1.00e3 并且没有任何变化。所以1.00e3 + 1 == 1.00e3

      在您的示例中也发生了同样的情况,只是我们正在处理更大的数字和原因基数。

      【讨论】:

      • 感谢更简单的语言:)
      • 不客气。我发现自己很难在 base2 中想象这一点。
      【解决方案3】:

      你应该使用括号来合并结果,然后减去 1,如下所示:

          System.out.println((long)Math.pow(2,63));
      
          System.out.println(((long)(Math.pow(2,63))-1));
      

      输出:

      9223372036854775807

      9223372036854775806

      【讨论】:

        【解决方案4】:

        对于java中的long数据类型,最大值为9,223,372,036,854,775,807(含)。 (2^63 -1)

        所以即使你尝试

        System.out.println((long)Math.pow(2,65));
        System.out.println((long)(Math.pow(2,63)-1));
        

        输出

        9223372036854775807
        9223372036854775807
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2010-12-05
          • 2013-07-07
          • 1970-01-01
          • 1970-01-01
          • 2012-10-31
          • 2013-01-22
          • 1970-01-01
          相关资源
          最近更新 更多