整数运算:乘除详解

66 篇文章 0 订阅
51 篇文章 0 订阅

 整数运算

无符号乘法:C语言中的无符号乘法被定义为产生w位的值

补码乘法:,C语言中的有符号乘法是通过将2w位的乘积截断为w位的方式实现的。

我们认为对于无符号和补码乘法来说,乘法运算的位级表示都是一样的,机器可以用一种乘法指令来进行有符号和无符号整数的乘法。

XDR库中的安全漏洞

包含安全漏洞的代码与下面所示类似:

/*

* Illustration of code vulnerability similar to that found in

* Sun's XDR library.

*/

void* copy.elements(void *ele_src □ , int element, size_t ele_size) {

/*

* Allocate buffer for element objects, each of ele_size bytes

* and copy from locations designated by ele_src

*/   •

void *result = malloc (ele_cnt * ele_size);

if (result == NULL)

/* malloc failed */

return NULL;

void *next = result;

int i;

for (i = 0; i < element; i++) {

/* Copy object i to destination */

memcpy(next, ele_src[i], ele_size);

/*   Move pointer      to next memory region */

next += ele_size;

}

return   result;

}

程序员用参ele_cnt等于1 048 577 (220+ 1)、 ele_size等 于4 096 (212)来调用这个函数。然后第10行上的乘法会溢出,导致只会分配4096个字节,而不 是装下这些数据所需要的4294 971 392个字节。从第16行开始的循环会试图复制所有的字节,超 越已分配的缓冲区的界限,因而破坏了其他的数据结构。这会导致程序崩清或者行为异常。

 

乘以常数:在大多数机器上,整数乘法指令相当慢,需要10个或者更多的时钟周期,我们会考虑乘以2的幂的情况,然后再概括成乘以任意常数。无论是无符号运算还是补码运算,乘以2的帯都可能会导致溢出。乘法比移位和加法的代价要大得多,许多C语言编译器试图以移位、加法和减法的组合来消除很多整数乘以常数的情况。

除以2的幂:在大多数机器上,整数除法要比整数乘法更慢——需要30个或者更多的时钟周期,整数除法总是舍入到零,移位总是舍入到零,这一结果与整数除法的规则一样。

 

算术右移不同位数,当需要进行舍人时,移位导致结果向下舍人,而不是像规则需要的那样向零舍入。例如,表达式-7/2应该得到-3,而不是-4。我们可以在移位之前“偏置”(biasing) 这个值,通过这种方法修正这种不合适的舍人,当y整除x时,我们得到k,否则,就得到k+1。

 

练习:

答案:

10100

10100

[100]4

[100]-4

1110

1110

[110]6

[110]-2

100100

100100

[100]4

[100]-4

答案:

 

 

答案:

int tmult_ok(int x,int y){
    int res1=x*y;
    long long res2 = x*y;
    return (int)res2==res1;
}

 

答案:

A.没有帮助,因为malloc的参数未改变,溢出的问题并没有根本解决。

B.当函数发生溢出时,则放弃缓冲区的分配。

long unsigned asize = ele_cnt*(long long unsigned)ele_size;
if(asize==(size_t)(ele_cnt*ele_size)) {
    void *result = malloc(asize);
}else{
    return nullptr;
}

 

答案:可以计算2n+1(n为0,1,2,3)或2n

 

答案:-(x<<m)

 

答案:

K

移位

加法/减法

表达式

6

2

1

(x<<2)+(x<<1)

31

1

1

x<<5-x

-6

2

1

(x<<1)-(x<<3)

55

2

2

(x<<7)-(x<<3)-x

 

答案:如果n-m>1选B,n-m=1任选,否则选A

 

答案:

int div16(int x){
   int bias=x>>31&0xf;
   return (x+bias)>>4;
}

 

答案:M为31,N为8

 

答案:

A:×,设x等于-2147483 648 (TMinz2)。 那么,有x-1等于2147483647 (TMaxz2).

B:√,若(x&7)!=7不成立,当且仅当x&7==7,此时x<<29后为E0000000<0成立。

C:×,x为非零成立,x为0时成立,若不成立,当且仅当x*x的最高位为1,即x*x必须溢出且第32位上的值为1则不成立。

D:√,当x为负成立,当x为正,-x恒为负,当x=0时成立

E:×,当x为-232不成立

F:√,补码和无符号位级操作相同

G:√,-y=~y+1

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值