U2
211275022田昊东¶
13、¶
x | y | |
---|---|---|
第一步 | a | a^b |
第二步 | a^a^b=b | a^b |
第三步 | b | b^a^b=a |
14、¶
- 当len为奇数时,处于数组中间位置的数会被置0,可能会导致结果不正确
- 最后一次循环中left=right=
(len-1)/2
- 最后一次调用后会将
a[(len-1)/2]
置零 - 修改循环条件
for(left=0;left<right;left++.right--)
15、¶
x | y | x^y | x&y | x|y | ~x|~y | x&!y | x&&y | x||y | !x||!y | x&&~y |
---|---|---|---|---|---|---|---|---|---|---|
0x5F | 0xA0 | 0xFF | 0x00 | 0xFF | 0xFF | 0x00 | 0x01 | 0x01 | 0x00 | 0x01 |
0xC7 | 0xF0 | 0x37 | 0xC0 | 0xF7 | 0x3F | 0x00 | 0x01 | 0x01 | 0x00 | 0x01 |
0x80 | 0x7F | 0xFF | 0x00 | 0xFF | 0xFF | 0x00 | 0x01 | 0x01 | 0x00 | 0x01 |
0x07 | 0x55 | 0x5E | 0x01 | 0x5F | 0xFE | 0x00 | 0x01 | 0x01 | 0x00 | 0x01 |
16、¶
x&=0xFF<<(n-8);
x&=0xFF;
x^=~0;x&=~0xFF;
x|=0xFF;
17、¶
b8 01 00 00
- 转化为二进制补码表示:
00000000 00000000 00000001 10111000
- 转化为真值:
440
14
- 转化为二进制补码表示:
00010100
- 转化为真值:
20
58 fe ff ff
- 转化为二进制补码表示:
11111111 11111111 11111110 01011000
- 转换回原码
10000000 00000000 00000001 10101000
- 转化为真值:
-424
74 fe ff ff
- 转化为二进制补码表示:
11111111 11111111 11111110 01110100
- 转换回原码
10000000 00000000 00000001 10001100
- 转化为真值:
-396
44
- 转化为二进制补码表示:
01000100
- 转化为真值:
68
c8 fe ff ff
- 转化为二进制补码表示:
11111111 11111111 11111110 11001000
- 转换回原码
10000000 00000000 00000001 00111000
- 转化为真值:
-312
10
- 转化为二进制补码表示:
00010000
- 转化为真值:
16
0c
- 转化为二进制补码表示:
00001100
- 转化为真值:
12
ec fe ff ff
- 转化为二进制补码表示:
11111111 11111111 11111110 11101100
- 转换回原码
10000000 00000000 00000001 00010100
- 转化为真值:
-276
20
- 转化为二进制补码表示:
00100000
- 转化为真值:
32
- 转化为二进制补码表示:
18、¶
- 当str2的长度大于str1的长度时会发生错误。
- 因为
strlen(str2)-strlen(str1)
会得到一个无符号整数,因此0也会被提升为无符号整数,因此strlen(str2)-strlen(str1)>0
恒成立,无法正确判断。 - 应该直接比较
return strlen(str1)>strlen(str2);
21、¶
arith
函数的目的是计算x*M+y/N
- 由于当乘除法可以转化为左右移操作时,系统会自动对其进行转化,来提高效率
optarith
中先将x左移4位然后又减去一个原先的x,这相当于x*=15
;然后对y右移2位,这相当于y/=4
- 所以:
M=15,N=4
30、¶
int ch_mul_overflow(int x,int y)
{
long long num=(long long)x*y;
int t=(num>>31)&1;
for(int i=0;i<32;i++)
{
if(((num>>(32+i))&1)!=t)
return 1;
}
return 0;
}
31、¶
-
不能修复溢出漏洞,由于malloc函数接收的参数为size_t类型(unsigned int),即使使用unsigned long long存储数据,在调用malloc进行数据传递时也会被转化为unsigned int类型。无法解决整数溢出漏洞。
-
修改方案:
-
由于malloc函数只能传入size_t类型参数,也就说发生溢出的原因是需要分配的空间大于malloc能够分配的内存的上限,因此可以在分配空间时先判断能否满足需求,如果不能则返回-1.
-
c //在2、3行之间插入以下判断 unsigned long long sum=count*(unsigned long long)sizeof(int); if(sum>0xffffffff) return -1;
34、¶
- 不永真:
x=0x0000C000
- 不永真:
x=0x80000000
- 永真:
- 当x<0时自然为真
- 当x>=0时,由于取-x一定不会发生溢出,因此一定有-x<=0
- 因此永真
- 不永真:
x=0x80000000
- 不用真:由于!=的优先级高于&所以相当于
x&0||(x<<28)<0
- 取
x=0
- 不永真:
x=0x80000000 y=0
- 不永真:
x=0xffffffff y=1
- 永真:
- (int)(ux-uy)=[x-y]补=[x]补+[-y]补=[-y]补+[x]补=[-y+x]补=[-(y-x)]补=-(y-x)
- 故该式永真
- 永真:因为右移是向-inf方向舍入,故不等式一定成立
- 永真:因为*4等价于左移2位,*8等价于左移3位
- 不永真:
x=-1 y=-1
- 左侧为0而右侧为-1
- 这是因为负数右移没有加偏移量,会导致向-inf舍入
- 永真:虽然结果在高位上可能不同,但在低位上是完全相同的,由于结果只取低位因此该式恒成立。
- 永真:alu加法器在进行运算时不区分是否有符号,因此等式左右的结果是相同的,恒成立。
- 永真:x*~y+ux*uy=x(-y-1)+xy=-xy-x+xy=-x
35、¶
- 永真:浮点数的符号位独立存储不会受到溢出的任何影响
- 不永真:因为int转化为float的过程中会造成精度的损失,是等式不一定成立
x=0x7fffffff
- 不永真:double的可表示范围比int大得多,可能int发生了溢出,而double没有
x=y=0x7fffffff
- 永真:因为double的精度高于int,因此把int转化为double进行计算不会发生舍入,因此等式恒成立
- 不永真:三个int相乘可能超过了double的精度,需要进行舍入
x=0x7ffffffa y=0x7ffffff2 z=0x7ffffff1
- 不永真:
x=0 y=1