1. 程式人生 > >《深入理解計算機系統》 練習題2.36答案

《深入理解計算機系統》 練習題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; }