论坛首页 Java企业应用论坛

int a=200*100000000;a =

浏览 13102 次
精华帖 (0) :: 良好帖 (1) :: 新手帖 (0) :: 隐藏帖 (3)
作者 正文
   发表时间:2011-10-09  
现在的IT人都不学操作系统课程么
0 请登录后投票
   发表时间:2011-10-09   最后修改:2011-10-09
public class MyInt {
	public MyInt(int num){
		this.num = num;
	}
	private int num;
	
	public int multiply(MyInt num) throws Exception{
		int sum = Math.abs(this.num) * Math.abs(num.getNum());
		if(sum < 0){
			throw new Exception("溢出了");
		}
		return this.num * num.getNum();
	}

	public int getNum() {
		return num;
	}
	
	public static void main(String[] args) throws Exception{
		MyInt a = new MyInt(1000000000);
		MyInt b = new MyInt(-20);
		System.out.println(a.multiply(b));
	}

}



以后你用这个做乘法吧。
0 请登录后投票
   发表时间:2011-10-09   最后修改:2011-10-09
楼主太钻牛角尖了
计算机认为溢出是正常现象,你不知道是因为知识的局限
你认为溢出是异常现象,那是因为你把它放在了具体的业务场景中,如金额等计算等

别人解释,你基本听不进去,还是细细看清楚吧。
0 请登录后投票
   发表时间:2011-10-09  
问你个问题,怎么判断是溢出了?除非改变CPU,否则没办法

CPU认为他的结果就是正确的,那么基于CPU运算结果的程序、虚拟机怎么可能判断?
或曰,正×正不可能为负数,比如200*1000000000结果是负数,可以抛异常,那么2000000*1000000000呢?这个结果是正数,而且比两个乘数都大,不抛错?
0 请登录后投票
   发表时间:2011-10-09  
captmjc 写道
问你个问题,怎么判断是溢出了?除非改变CPU,否则没办法

CPU认为他的结果就是正确的,那么基于CPU运算结果的程序、虚拟机怎么可能判断?
或曰,正×正不可能为负数,比如200*1000000000结果是负数,可以抛异常,那么2000000*1000000000呢?这个结果是正数,而且比两个乘数都大,不抛错?

查标志寄存器的OF标志位。
这个都判断不出来,程序真没法写了 = =#
0 请登录后投票
   发表时间:2011-10-09  
允许溢出计算只能认为是为了某些效率,溢出=错误 这个是肯定的!
0 请登录后投票
   发表时间:2011-10-09  
aa87963014 写道
允许溢出计算只能认为是为了某些效率,溢出=错误 这个是肯定的!

-1 + 1 = 0 ,在计算机计算溢出了
溢出 = 错误
那么-1 + 1 = 0 是肯定错误的了
我明白了
凡是-x + x = 0都是错误的
0 请登录后投票
   发表时间:2011-10-09  
hand515 写道
aa87963014 写道
允许溢出计算只能认为是为了某些效率,溢出=错误 这个是肯定的!

-1 + 1 = 0 ,在计算机计算溢出了
溢出 = 错误
那么-1 + 1 = 0 是肯定错误的了
我明白了
凡是-x + x = 0都是错误的

虽然我没太了解计算机计算过程,-1+1=0就一定要溢出?一定要溢出才有”正确“结果??
0 请登录后投票
   发表时间:2011-10-10   最后修改:2011-10-10
aa87963014 写道
hand515 写道
aa87963014 写道
允许溢出计算只能认为是为了某些效率,溢出=错误 这个是肯定的!

-1 + 1 = 0 ,在计算机计算溢出了
溢出 = 错误
那么-1 + 1 = 0 是肯定错误的了
我明白了
凡是-x + x = 0都是错误的

虽然我没太了解计算机计算过程,-1+1=0就一定要溢出?一定要溢出才有”正确“结果??


是的,准确来说,不是溢出,这叫丢弃进位。溢出是人类的想法,对计算机来说,只是把多出来的进位直接丢弃了。例如你在32位的机器上做加法,如果要进位到第33位,那么这个进位就被写到标志寄存器里,而实际做加法的位置就把这个进位丢弃了。当然你可以在做完加法之后立刻自己去检查进位寄存器,然后自己处理,但计算机不会管你的事情。而且,丢弃进位计算机计算减法的基础。

你说是为了效率引入了(人类认为的)错误,也不错。不过在计算机里这种事情多了,例如:

数组第一个元素的序号是0,不是1
在很多语言里(例如C),数组引用超界不算是异常
null这个概念本身就是个错误,连null这个关键字的发明人也说过,因为当年一念之差,为开发界带来了巨额的金钱损失。( http://www.infoq.com/presentations/Null-References-The-Billion-Dollar-Mistake-Tony-Hoare )

但是从计算机的角度看,矫正这些错误代价太大了。象你说的自动判断溢出,在计算机内部的每次加法运算必须要记录你参与运算的数据类型,然后再做一次额外的判断。而加法运算速度是评价计算机运算速度的最基本的标准,所谓的xxx万次计算机,就是指一秒内能计算xxx万次加法。加入溢出判断,一下子就至少把速度减下来三分二(还是假定记录类型和判断溢出本身不涉及加法的情况),你想想这会带来多大的性能损失。

实际开发中,如果你不想溢出,就用BigDecimal。语言规范明确说明Integer和Long这些类型都会溢出,java也提供了不会溢出的BigDecimal。
0 请登录后投票
   发表时间:2011-10-10  
aa87963014 写道
543089122 写道



计算机又不知道计算出的结果毫无意义,人家只知道除0它搞不定(抛异常),其他都能搞定



这个结果本身属于溢出。既然溢出本身就应该是错的。既然知道除0是错的(抛异常)
为何溢出又不是错的,不抛异常?

谁说滴
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics