黑马程序员技术交流社区

标题: 请教:关于赋值运算符+=的问题 [打印本页]

作者: 黑龙江—刘鹏    时间: 2012-7-6 22:56
标题: 请教:关于赋值运算符+=的问题
本帖最后由 黑龙江—刘鹏 于 2012-7-6 23:47 编辑

class lianxi
{
        public static void main(String[] args)
        {
        

        short s = 3,s1=2;
        
        s+=322;
        s1+=32768;
        System.out.println(s+"+"+s1);
        }
}
这个代码打印出来的结果是 325+-32766
我想知道 325 与 -32766 是什么数据类型的 是int嗨是short  为什么 s1+=32768变成了负数呢?
{:3_62:}
为什么 short类型的范围是 2^15-1呢?
这个难道是规定?还是有某种目的的规定 什么目的?
作者: 邵阳    时间: 2012-7-6 22:58
本帖最后由 邵阳 于 2012-7-7 09:06 编辑

class lianxi
{
        public static void main(String[] args)
        {
        

        short s = 3,s1=2;
        
        s+=322;            //相当于,但是这个s=会编译出错,因为java默认基本数据类型是int,
                                    //s+322   会被自动转化为int类型,而s仍是short类型,所以编译出错。
                                  //而+=则自动完成强转操作,相当于s=short(s+2)。  
s1+=32768;   //同上
        System.out.println(s+"+"+s1);
        }
}

325 与 -32766都是是short类型。因为+=会自动完成。

为什么是负数?是因为超过了short的范围,short的范围是-32768~32767。
第十三楼答案很好




作者: 黑龙江—刘鹏    时间: 2012-7-6 23:01
邵阳 发表于 2012-7-6 22:58
class lianxi
{
        public static void main(String[] args)

嗯 那么为什么+2应该是32770呀 为什么变成负数了
作者: 李志群    时间: 2012-7-6 23:12
class lianxi
{
         public static void main(String[] args)
         {
         

        short s = 3,s1=2;
         
        s+=322;//这个可以看成是 s+=322  s=322+3 所以s的值是325
         s1+=32768;//这个可以看成是 s1+=32768+2  所以结果是-32766,因为你定义的是short型超出了他的范围。Short短整型 16位 –32,768 ~ 32,767
         System.out.println(s+"+"+s1);//把上面的结果用输出就是楼主所说的结果哦
         }
}
希望采纳!
作者: 黑龙江—刘鹏    时间: 2012-7-6 23:15
李志群 发表于 2012-7-6 23:12
class lianxi
{
         public static void main(String[] args)

哦了  那么 为什么 short类型的范围 是 2^15-1呢 为什么-1呢
作者: 李志群    时间: 2012-7-6 23:17
这个我也就不清楚了 要问创建java语法的人啦 呵呵 :)呵呵 我是看书上面这么写的都是呵呵
作者: 黑龙江—刘鹏    时间: 2012-7-6 23:21
李志群 发表于 2012-7-6 23:17
这个我也就不清楚了 要问创建java语法的人啦 呵呵 呵呵 我是看书上面这么写的都是呵呵 ...

嗯 嘿嘿
作者: 黑龙江—刘鹏    时间: 2012-7-6 23:21
邵阳 发表于 2012-7-6 22:58
class lianxi
{
        public static void main(String[] args)

嗯 谢谢啦 这个我懂了
作者: 付蛟龙    时间: 2012-7-6 23:23
在java中 short类型变量占两字节 所以其表示的数据范围为 -2^15~2^15-1
十进制范围为 -32768~32767  你的程序中 s1+=32768 ;  运算结果为 65536 (2^16),会发生溢出
作者: 张昊镭    时间: 2012-7-6 23:28
邵阳 发表于 2012-7-6 22:58
class lianxi
{
        public static void main(String[] args)

呃,我跟lz是同样的疑问,还是没弄懂那个超出范围的怎么计算来的。按照你的蓝字的解释,我还是太愚钝,没懂,我只是强记了计算方式,是这样:
两数相加-short的上限-1+shoort的下限
就是:2+32768-32767-1+(-32768)=-32766
哎 ,不懂到底为啥这么算。


作者: 黑龙江—刘鹏    时间: 2012-7-6 23:30
张昊镭 发表于 2012-7-6 23:28
呃,我跟lz是同样的疑问,还是没弄懂那个超出范围的怎么计算来的。按照你的蓝字的解释,我还是太愚钝,没 ...

嗯 他们说short的正数范围到 32767
作者: 孙飞    时间: 2012-7-6 23:30
本帖最后由 feigecal 于 2012-7-7 00:15 编辑

short是有符号数据,它有一个范围,32768超出了short的范围,所以在运算过程中会溢出。溢出后short会从最小值-32768开始存储,就是说在-32768的基础上再加上多出的数,也就是-32768+2,所以是-32766.下面是我对计算机内部运算的看法,首先,负数在计算机中是以其补码形式存在的,就是它绝对值的二进制原码按位取反后加1。先看32768的二进制表示为1000  0000  0000  0000,它的按位取反后是0111 1111 1111 1111,然后再加1吧就成为了1000  0000  0000  0000,所以-32768在计算机中表示为1000  0000  0000  0000,复合赋值运算符不改结果的类型,所以在计算机中运算它加上2就是-32766了
作者: 高原    时间: 2012-7-6 23:34
本帖最后由 高原 于 2012-7-6 23:37 编辑
黑龙江—刘鹏 发表于 2012-7-6 23:01
嗯 那么为什么+2应该是32770呀 为什么变成负数了

s1 += 32768  -》s1 = s1 + 32768
32768是 int 型,和  s1  相加时,s1 自动类型提升,先转化为 int 型,计算结束时候再转回 short型

二进制补码转十进制:如果是正数(最高位是0),直接按照普通方法求,如:0000...110: 1*2的2次幂 + 1*2的1次幂 + 0*2的0次幂 = 6
如果是负数(最高位是1),先将所有位取反,然后末位加 1,得到的二进制位按照正数来求,求得的结果前面加负号即可
10000000 00000010--》取反:01111111 11111101  --》加1:01111111 11111110 --》32766 --》前面加负号:--》-32766
下面是图:

捕获.PNG (48.46 KB, 下载次数: 25)

捕获.PNG

作者: 付蛟龙    时间: 2012-7-6 23:34
不好意思 看错了 把你的s1初值看成32768了

在java中 short类型变量占两字节 所以其表示的数据范围为 -2^15~2^15-1
十进制范围为 -32768~32767  你的程序中 s1+=32768 ;  运算结果为 32770 (2^15+2),超出其范围 会发生溢出  

至于第二个问题  为什么 short类型的范围 是 2^15-1呢 为什么-1呢

因为short是有符号的嘛  当首位是1是 表示这个数是负数  当高位时0时,表示正数 那么很明显了   正数最高位永远是0了    也就是表示数值的有效位也只有16-1=15位了  最大也就是 0111 1111 1111 1111——> 2^15-1了


作者: 黑龙江—刘鹏    时间: 2012-7-6 23:45
哦了 我终于知道了  2^5=32       2^0+2^1+2^2+2^3+2^4=31   2^5-1=31咯
而 2^5在电脑是  最高位是1所以是负数了 是-32咯
作者: 孙飞    时间: 2012-7-7 00:07
关于范围嘛,我这样理解,因为short是有符号数据,最前面是1代表负数,所以先找负数的范围,把最左边位上写1,因为是负数,加上一个正数都会减小范围,所以最左边除外其它位上都是0就是负数方的范围等于是把1左移了15位再加上负号,左移n位就是乘以2的n次方,所以是负的2的15次方。再说正数范围,因为最左边的必须是0以代表正数,那么最大就是其余全是1了,就是0111 1111 1111 1111,这个数加上1就是1000 0000 0000 0000,也就是负数范围的绝对值就是2的15次方,所以正数范围就是2的15次方减1。




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2