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储存,这样才能得到正确的结果...真意外 啊啊啊.

原文地址:https://www.cnblogs.com/yhlx/p/2953635.html