黑马程序员技术交流社区

标题: 正在自学遇到个问题一直想不明白,求各位大神指点~ [打印本页]

作者: 立志转行    时间: 2015-5-5 18:19
标题: 正在自学遇到个问题一直想不明白,求各位大神指点~
(1)  比如int x = 4331;

x = x/1000;
然后输出x,不报错,但是结果是4,是不是这就叫损失了精度?但为什么不报错?
(2)然后用short又尝试了下
short x = 4331;
x = x/1000;
然后输出x,报错,int 转short损失精度;
为什么会是int转short损失精度?是因为1000默认为int?
(3)再尝试
short x = 4331,y = 1000;
x = x/y;
然后输出,报错,int转short损失精度;
这个int怎么来的?x y都定义为short了何来int?
(4)加法也是
int x = 2000000000,y = 2000001111;
x = x + y;
输出x,不报错,但是结果是负数;
都已经超过int取值范围了,而且结果都错了,为什么还不报错?
(5)short加法
short x = 31111,y = 30000;
x = x+y;
输出,报错,int转short损失精度;
为什么int超了,结果错了都不报错?short就报错?求大神指点,小白真的不明白。


作者: 立志转行    时间: 2015-5-5 18:26
看见论坛不让发小白问题,不知道这个算不算?犹豫了好久还是发了。。。求解惑?
作者: 立志转行    时间: 2015-5-5 19:14
自顶~快来人啊
作者: 1017161726    时间: 2015-5-5 21:03
1.int类型除以int类型,在数学上虽然结果是小数,但是要赋给一个int型x,小数部分要去掉。这个不会损失精度。损失精度的定义是,系统给一个变量分配固定的空间,比如int,长度固定32 bit,如果你要把它变成short类型的16 bit,系统就会自动把int整数的前面16位去掉,如果这16位中不全是0,那么就损失精度。所以你把一个整数从更高类型转为比较低的类型,就会报错:容易损失精度。

2.short类型和1000相除,系统默认认为1000是int型,short和int一起运算,就会有类型提升,因为short和int不是一个等级的。但是总不能让32位的int 转成16位的short吧,那样不合适,容易丢失数据的。所以就把16位的short转成32位的int了,在short的后面加了16个0,运算结果也是int型的。然后又赋给short型,这又涉及到这个问题 了。int转short要去掉前面的16位,很容易丢失数据。所以报错。

3.两个short一起运算,结果还是会自动提升为int,我当时就是强记的。这个可能是因为两个长度都比较短的整数相加很可能超出范围,所以都转成默认整型int的。

4.int型最大正整数是2147483647,你很明显在正数区域超范围了,而两个int型相加没有转问题。
从二进制的角度来看,int型2147483647  再加1,结果是-2147483648,所以只要你数值不超过2147483648*2 - 1,就还是int型。
这个你可以参考我的帖子:http://bbs.itheima.com/thread-192224-1-1.html   后半部分有这个分析,希望你看得懂。

5.这个也是两个short相加,结果必是int。你也看到了,你传值快超过short最大值32767了。你来两个3万多的数相加,有可能出错的。所以java会默认给你一个强转吧,转成相对来说足够大的int型,很大程度上减少出错。







作者: 王英明    时间: 2015-5-5 21:06
看看,没力气啊!
作者: brouse    时间: 2015-5-5 21:14
这是自动升格的问题,到时候会详细讲的,小的可以自动变大的,大的不能变小的
作者: 陈文超    时间: 2015-5-5 21:19
1.x/1000是两个整型的 是整除,4331/1000 = 4余331 也就是 4331%1000 = 331
作者: 陈文超    时间: 2015-5-5 21:20
1.x/1000是两个整型的 是整除,4331/1000 = 4余331 也就是 4331%1000 = 331

作者: wkz_crystal    时间: 2015-5-5 21:26
我之前也非常疑惑,现在明白了,你只要记住就OK了:
【1】
比较好理解:x是int类型,1000我们知道默认的是int类型,int/int还是int类型,取整数部分哈
【2】
1000默认的是int类型,理解就很简单了吧,x/1000,重点是x做了类型的自动提升(由short到int),int/int
=int,该int类型的值再付给x的short类型必然损失精度,所以一样正确的写法是:x=(short)(x/1000);
或者写成x /=1000,也是非常OK的
【3】
产生这样原因是:short/short=其实具体来说,得到的是一个Integer类型对象的数据,所以,自然也要
进行转换:x =(short)( x/y);这样一切就ok了!
【4】
int类型的最大值是2147483647,int x = 2000000000,y = 2000001111;中x+y必然会超出范围,不报错的原因是:都是按照二进制的方式就行加法运算,
超出最大值的限制之后,(就是所谓的溢出),最高位可能会变为1,也就是表示负数,所以结果为负数
【5】
对于short方式的加法运算,自己分析吧,应该不难了吧!

作者: 立志转行    时间: 2015-5-5 23:10
1017161726 发表于 2015-5-5 21:03
1.int类型除以int类型,在数学上虽然结果是小数,但是要赋给一个int型x,小数部分要去掉。这个不会损失精度 ...

看了你的帖,integer目前还没学到,但是你的意思大概明白了,是不是说int x++永远属于int?它会按照你说的那个圈一直循环?但是你用byte举得例子,byte是不是和short一样会默认强转吧?那就报错了,不可能得出值了,也不存在循环了?
作者: 1017161726    时间: 2015-5-5 23:13
立志转行 发表于 2015-5-5 23:10
看了你的帖,integer目前还没学到,但是你的意思大概明白了,是不是说int x++永远属于int?它会按照你说 ...

语句写成byte x=x+1,是会强转的。
但是写成byte x+=1,就不会强转。我是这么写的,所以不会有强转。
作者: 立志转行    时间: 2015-5-5 23:13
陈文超 发表于 2015-5-5 21:19
1.x/1000是两个整型的 是整除,4331/1000 = 4余331 也就是 4331%1000 = 331

/代表的不是整除的意思吧?我定义成float后会得出小数,应该是楼上说的,进行了强转吧?
作者: 立志转行    时间: 2015-5-5 23:17
wkz_crystal 发表于 2015-5-5 21:26
我之前也非常疑惑,现在明白了,你只要记住就OK了:
【1】
比较好理解:x是int类型,1000我们知道默认的是i ...

integer还没学到先记住,第4条中说是按二进制的方式运算的,但是byte、short也是用二进制运算的吧
作者: 立志转行    时间: 2015-5-5 23:27
1017161726 发表于 2015-5-5 23:13
语句写成byte x=x+1,是会强转的。
但是写成byte x+=1,就不会强转。我是这么写的,所以不会有强转。 ...

是是!你解释了x+=1是因为二进制方式运算的所以不报错,没有解释y = x + 1,能给我说说问什么不一样吗?y = x + 1不是也用的二进制进行计算吗?是不是还没学到?表示看不懂、、、、
作者: w401634075    时间: 2015-5-6 00:49
损失精度的理解上有问题的。第一个那个叫取整。损失精度一般是由于把大的转成小的会损失精度。
作者: 横看成岭侧成锋    时间: 2015-5-6 01:33
不简单啊
作者: 1017161726    时间: 2015-5-6 08:26
立志转行 发表于 2015-5-5 23:27
是是!你解释了x+=1是因为二进制方式运算的所以不报错,没有解释y = x + 1,能给我说说问什么不一样吗?y  ...

y=x+1,这个整数 1,默认是int型。如果x也是int型,就不会有强转,其他的就要根据情况强转了。
作者: wkz_crystal    时间: 2015-5-6 14:00
立志转行 发表于 2015-5-5 23:17
integer还没学到先记住,第4条中说是按二进制的方式运算的,但是byte、short也是用二进制运算的吧 ...

对,都是按照二进制运算的,【4】中,我主要是强调而已,呵呵!
作者: IDhmpj    时间: 2015-5-6 20:25
立志转行 发表于 2015-5-5 23:17
integer还没学到先记住,第4条中说是按二进制的方式运算的,但是byte、short也是用二进制运算的吧 ...

精度小于int的数值运算的时候都会被自动转换为int后进行计算
作者: bboyXiaoNuo    时间: 2015-5-6 21:10
4楼活雷锋 啊,正解看四楼
作者: 大可乐    时间: 2015-5-6 21:14
加油、、、、、、、、
作者: 立志转行    时间: 2015-5-7 12:20
1017161726 发表于 2015-5-6 08:26
y=x+1,这个整数 1,默认是int型。如果x也是int型,就不会有强转,其他的就要根据情况强转了。 ...

大概明白了!谢谢大神~
作者: Oh.Ba    时间: 2015-5-7 18:52
编译时检查语法,但是并没有计算你值到底为多少,只要语法没错误就能编译通过。
作者: lshaizj    时间: 2015-5-7 19:06
学习了 非常不做
作者: 立志转行    时间: 2015-5-7 22:22
Oh.Ba 发表于 2015-5-7 18:52
编译时检查语法,但是并没有计算你值到底为多少,只要语法没错误就能编译通过。 ...

对对!只检查语法,懂了~
作者: 秋明    时间: 2015-6-8 17:31
本帖最后由 秋明 于 2015-6-8 18:38 编辑

楼主的疑问4l大概都说了,但是从楼主的问题来看,楼主对数据在内存中的存储以及读写方式理解的还不是很透彻,否则,也不会有此疑问了,所以我这里补充两点题外的东西。
一、编译器只检查语法错误,换句话说,编译通过,只代表语法没有错误,不代表逻辑没有错误,把int型变量转为短整型short,在逻辑上就是错误的,这就好比只能放2个苹果的盒子,你硬要放4个进去....结果要么是编译器度量大,通过了编译了,但是会让内存扣掉你两个苹果,要么就是直接给你脸色看了(报错,编译不通过)。计算机就是根据人的逻辑设计出来的,所以一定要站在人的逻辑上想问题,杀鸡可以用牛刀,但是杀牛是不能用杀鸡的刀子的,就算杀死了,牛也会疯的。小的可以放大的里面,大的不能放小的里面,这是符合人的逻辑的。
二、楼主对待这些问题时,大脑中一定要有内存的模型,比如可以把x、y、还有常量想想成内存中独立的块儿,每个块儿类型是不一样的,这样在运算过程中自然会产生4l所说的情况。举个简单例子,希望帮助楼主更好的理解内存,y=x+z  这三个变量在内存中就是三个箱子,根据变量的类型,箱子的大小也不一样,假设,xz都是short牌的小箱子,里面都放了2个苹果,y是int牌的大箱子,然后要算一下这xz这两个箱子里总共有多少个苹果,内存是这样做的,把x中的2苹果和z中的两个苹果都移到y中,然后cpu读一下y中有多少个苹果,然后再写到y中,并贴上int牌的标签,然后你打印出来y中的值就是xz两个箱子苹果的总数,在这个过程中,类型的转换是很自然很符合逻辑的。当然,也有先转(强转)后计算的情况,cpu先从内存中先把xz的值取出来,相加后,再把结果写到变量y中,楼主理解了我前面说的,后面就不难理解了吧。希望对楼主的疑问能有所帮助,不对之处,请大家指出。
作者: 秋明    时间: 2015-6-8 17:36
本帖最后由 秋明 于 2015-6-8 17:56 编辑

26l打错的地方已经修改。
作者: mishisanyi    时间: 2015-6-8 20:04
(1)  比如int x = 4331;
x = x/1000;
然后输出x,不报错,但是结果是4,是不是这就叫损失了精度?但为什么不报错?
对:损失了精度,因为int类型本省就是裁剪掉浮点类型的值,你可以尝试一下 int i = (int)4.331;
(2)然后用short又尝试了下
short x = 4331;
x = x/1000;
然后输出x,报错,int 转short损失精度;
为什么会是int转short损失精度?是因为1000默认为int?
报错是因为自动类型转换,X/1000的结果是4是个int类型的,不能直接赋值给int
(3)再尝试
short x = 4331,y = 1000;
x = x/y;
然后输出,报错,int转short损失精度;
这个int怎么来的?x y都定义为short了何来int?
还是上面的结果,它会自动转换成int,你要赋值,可以使用显示转换,即(short)
(4)加法也是
int x = 2000000000,y = 2000001111;
x = x + y;
输出x,不报错,但是结果是负数;
都已经超过int取值范围了,而且结果都错了,为什么还不报错?
超过int取值范围不会出错,建议你可以看看int类型定义时的内存结构是怎样的
(5)short加法
short x = 31111,y = 30000;
x = x+y;
输出,报错,int转short损失精度;
为什么int超了,结果错了都不报错?short就报错?求大神指点,小白真的不明白。
这道题和所有的一样,short类型只要有操作,会自动转换成int类型,其次,int超范围了,不代表会出错,只会变成负数,你可以看看内存存储结构

作者: 付欢    时间: 2015-6-8 21:24
1017161726 发表于 2015-5-5 21:03
1.int类型除以int类型,在数学上虽然结果是小数,但是要赋给一个int型x,小数部分要去掉。这个不会损失精度 ...

讲解的很详细啊,学习了:victory:




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