《深入理解计算机系统》 练习题2.36答案

强制类型转换与其他运算的先后

int main(void)
{
	int x = -pow(2, sizeof(int) * 8 - 1); /* Tmin */
	int y = -1;

	auto z1 = (int64_t)x * y;
	auto z2 = x * (int64_t)y;
	auto z3 = (int64_t)x * (int64_t)y;
	auto z4 = (int64_t)(x * y);
}

在这里插入图片描述
注意z1变量,是先进行类型转换,然后再执行乘法,再会隐式地将y进行类型转换,再继续执行乘法。
z2,z3变量都是一回事。
注意z4变量,(x * y)这里还是int型的,所以这里正溢出,进行截断,还是-2147483648。然后进行类型转换,即进行位拓展,新拓展的位上的值都为1。

代码

此函数为初始版本,是用除法来检测的:

int tmult_ok(int32_t x, int32_t y)
{
	int32_t p = x * y;

	/* Either x is zero, or dividing p by x gives y */
	return !x || p / x == y;
}

先提前扩大两个数的范围,再执行乘法。
然后再进行截断,因为截断之后就相当于把乘积mod 2322^{32},取余2322^{32}的范围为【0,2322^{32}-1】。如果截断以后,值不相等,那么就出现溢出了。

int tmult_ok2(int32_t x, int32_t y)
{
	int64_t p = (int64_t)x * y; /*一定要先将右边手动转成 int64_t */
	/*printf("p=%" PRId64 ", q=%" PRId32 "\n", p,q);*/

	return p == (int32_t)p;
}

参考链接:
[1] https://github.com/vonzhou/CSAPP/blob/master/exercise/ex2-36.c
[2] https://github.com/haiiiiiyun/book_exercises/blob/master/csapp-v3/chap2/2.36.c

posted @ 2018-11-08 21:25  allMayMight  阅读(123)  评论(0编辑  收藏  举报