《深入理解計算機系統》 練習題2.36答案
阿新 • • 發佈:2018-12-20
強制型別轉換與其他運算的先後
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 ,取餘的範圍為【0,-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;
}