• 谜题三:长整除


    public class LongDivision{
      public static void main(String args[]){
        final long MICROS_PER_DAY = 24 * 60 * 60 * 1000 * 1000;
        final long MILLIS_PER_DAY = 24 * 60 * 60 * 1000;
        System.out.println(MICROS_PER_DAY/MILLIS_PER_DAY);
      }

    }
    这样看来好像很简单,除数中所有的因都被约掉了,只下 1000,这正是每毫秒包含的微秒数。

    除数和被除数都是 long 类型的,long 类到了可以很容易地保存这两个乘而不产生溢出

    因此,看起来程序打印定是 1000。

    然而程序运行结果却是 ‘5’

    不可思议。。

    原因在书中说:“这个计
    算完全是以 int 运算来执行的,并且只有在运算完成之后,其结果才被提升到
    long,而此时已经太迟了:计算已经溢出了,它返回的是一个小了 200 倍的数值。
    从 int 提升到 long 是一种拓宽原始类型转换(widening primitive conversion),
    它保留了(不正确的)数值。这个值之后被 MILLIS_PER_DAY 整除,而
    MILLIS_PER_DAY 的计算是正确的,因为它适合 int 运算。这样整除的结果就得
    到了 5。

    第一个因子被程序看成了int,因此先用int来执行,没有计算完,就超出了int的存储范围溢出了,缩水了很多倍,所以依照它的说法,稍微改动一下程序就可以改正了,比如:

    这个结果就是1000了,很显然,把第一个因子强制定义为long类型,不溢出,结果自然就正确了。。。

  • 相关阅读:
    STL_算法_05_集合算法
    STL_算法_04_算术和生成算法
    STL_算法_03_拷贝和替换算法
    STL_算法_02_排序算法
    STL_算法_01_查找算法
    STL_容器使用时机
    STL_容器共通能力
    Qt5_选择文件对话框
    Qt5_当前exe所在路径
    Java 静态代理和动态代理
  • 原文地址:https://www.cnblogs.com/applemy/p/6479816.html
Copyright © 2020-2023  润新知