• 博客园logo
  • 会员
  • 周边
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录

绝望生鱼片

  • 博客园
  • 联系
  • 订阅
  • 管理

公告

View Post

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

posted on 2013-03-11 11:14  绝望生鱼片  阅读(2844)  评论(0)    收藏  举报

刷新页面返回顶部
 
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3