今天在看框架的工具包时发现了一个细节,
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,
看了《Java虚拟机说明书》中“Java语言编程概念”中对“基本数据类型的变窄转换”的介绍才算明白了。
对于
int i = 1000000;
System.out.println(i*i);
-----------------------
-727379968
-----------------------
的合理解释和过程应该是这样的:
Java定义了若干使用于表达式的类型提升规则:
1) 所有的byte型. short型和char型将被提升到int型(例外: final修饰的short, char变量相加后不会被自动提升。)
2)如果一个操作数是long形 计算结果就是long型;
3)如果一个操作数是float型,计算结果就是float型;
4)如果一个操作数是double型,计算结果就是double型;
下面用一个十六进制表示的例子阐释这个问题
int i3 = 1000000;
System.out.println ((i3*i3));
System.out.println ("溢出:"+Long.toHexString (i3*i3).toUpperCase());
System.out.println ("long*int返回long所以未溢出:"
+Long.toHexString ((long)i3*i3).toUpperCase());
System.out.println ("将溢出后的int值转换成long仍然是错误的:"
+Long.toHexString ((long)(i3*i3)).toUpperCase());
System.out.println ("输出溢出后的int值:"
+Integer.toHexString (i3*i3).toUpperCase());
---------------------------------------------------
-727379968
溢出:FFFFFFFFD4A51000
long*int返回long所以未溢出:E8D4A51000
将溢出后的int值转换成long仍然是错误的:FFFFFFFFD4A51000
输出溢出后的int值:D4A51000
---------------------------------------------------
截取是非常直观的
原来如此,于是加了d的1024相乘,结果就会以double储存,这样才能得到正确的结果...真意外 啊啊啊.