在高级语言中,两个n位整数相乘得到的结果通常也是一个n位整数,即结果只取2n位乘积中的低n位。这导致乘法运算得到结果必须在范围: -2n-1<= x*y < 2n-1才不会溢出。


假设为4位,进行52

0101
		*   0101
		--------
		    0101
		+ 0101
		--------         只取4位,即1001  为1111的补码 即为-7
		00011001
			----

在二进制乘法运算下,只有1*1等于1;
再列如:32

0011
	*	0011
	--------
	    0011
	+  0011        1001同样为1001 也为-7的补码
	--------
	00001001   
		----

运算溢出会给程序带来意想不到的结果

int mult(int x,int y){
	int z=x*y;
	if(!x||z/x==y) return z;
	//这样的设计能避免溢出得到错误的数据
}

注意:
1、当x、y、z都是unsigned int时,只需要根据乘积的高n位是否为全0,进行判断溢出,全为0,则不溢出。

这与unsigned的特性有关,因为它无负数,故最高位的符号位也充当存储数值的功能。如果是一个n位的乘法,它的取值范围只能:0~2n-1之间,然而进行n位的乘法会得到一个2n位的数据,而乘法的结果只保留低n位,故在不溢出的情况下,高n位只能全为0.

2、若高n位全为0或全为1且等于低n位的最高位,则不溢出。

两个int相加java 两个int相乘结果类型_数据


在MIPS处理器中,mult会将两个32位带符号整数相乘,得到的64位乘积置于两个32位内部寄存器Hi和Lo中,因此,可以根据Hi寄存器中的每一个位值是否等于Lo中的最高位进行溢出判断。

注:乘法指令不产生溢出标志


整数乘法溢出漏洞


int copy_array(int* array,int count){
	int *myarray=(int*)malloc(count*sizeof(int));
	if(myarray==NULL){
		return -1;
	}
	for(int i=0;i<count;i++)
		myarray[i]=array[i];
	return count;
}

当参数count很大时,则count*sizeof(int)会溢出。
malloc会在堆一段能容纳需要大小的连续空间分配,在进行越出访问时,可能会破坏堆(heap)中的大量数据。


整数乘法运算比较移位和加法等运算所用时间长,,因此,编译器在处理变量与常数相乘时,往往以移位、加法和减法的组合运算来代替乘法运算。

例如:对于表达式x20,编译器可以利用 20=16+4=24+22,将x20转换为(x<<4)+(x<<2),这样,一次乘法转换两次移位和一次加法。