• java int 乘法溢出问题


    今天在看框架的工具包时发现了一个细节,

    double d=1024d * 1024 * 1024 * 1024;

    第一个1024后面为什么要带个d呢?

    于是我尝试了一下:

    double d = 1024d * 1024 * 1024 * 1024;
    double dw = 1024 * 1024 * 1024 * 1024 ;
    System.out.println(d);
    System.out.println(dw);

    结果为:

    1.099511627776E12
    0

    --------------

    0?为啥是0?? java的普通数字类型是int,1024是int,4个int的1024相乘(2^40)已经超出了int的表示范围了,2^32,

    http://bbs.csdn.net/topics/40216116

    看了《Java虚拟机说明书》中“Java语言编程概念”中对“基本数据类型的变窄转换”的介绍才算明白了。

        对于

    int i = 1000000;
    System.out.println(i*i);
    -----------------------
    -727379968
    -----------------------

        的合理解释和过程应该是这样的:
        i设置为1000000,在乘方时Java发现结果(1000000000000)已经超出了int基本数据类型的最大范围(2147483647),于是作了默认的类型提升(type promotion),中间结果做为long类型存放,返回结果时目标数据类型int不能够容纳下结果,于是根据Java的基础类型的变窄转换(Narrowing primitive conversion)规则,把结果宽于int类型宽度的部分全部丢弃,也就是只取结果的低32位,于是就得到了上面的结果。
       下面用一个十六进制表示的例子阐释这个问题
        int i3 = 1000000;
        System.out.println (Long.toHexString (i3*i3).toUpperCase());
        System.out.println (Long.toHexString (i3*i3).toUpperCase());
        System.out.println (Integer.toHexString (i3*i3).toUpperCase());
        System.out.println ((int)i3*i3);
    ---------------------------------------------------
    FFFFFFFFD4A51000
    1000000000000
    D4A51000
    -727379968
    ---------------------------------------------------

       截取是非常直观的

    原来如此,于是加了d的1024相乘,结果就会以double储存,这样才能得到正确的结果...真意外 啊啊啊.

  • 相关阅读:
    Android中使用File文件进行数据存储
    Android 获取 json
    Android服务之Service
    php
    宝塔数据库连接不上
    idea中使用github
    elasticjob 当当的分布式定时任务管理
    定时任务规则生成器
    MySQL中group_concat()函数的排序方法
    mysql 中关于怎么写 row_number()over(order by) 类似的功能支持
  • 原文地址:https://www.cnblogs.com/yhlx/p/2953635.html
Copyright © 2020-2023  润新知