整数乘法运算

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


假设为4位,进行52

			0101
		*   0101
		--------
		    0101
		+ 0101
		--------         只取4位,即10011111的补码 即为-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位的最高位,则不溢出。
在这里插入图片描述


在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),这样,一次乘法转换两次移位和一次加法。

  • 4
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值