演習 3-4
無職の間にK&Rを再読。演習問題の解答をさらす。解く順番は適当。
演習 3-4
2の補数表現においては、われわれの itoa プログラムでは、最大の負の数、すなわち -(2wordsize-1) に等しい n の値が処理できない。なぜダメか説明せよ。また、計算機のいかんにかかわらずこの値を正確に印字するように、これを修正せよ。
Exercise 3-4
In a two's complement number representation, our version of itoa does not handle the largest negative number, that is, the value of n equal to -(2wordsize-1). Explain why not. Modify it to print that thw value correctly, regardless of the machine on which it runs.
説明せよ。2の補数表現で1バイトを表現したとき -128 から 127 までの範囲をとる、すなわち最大の負の数 -128 に対応する正の数 128 を表現できない。
負の数を正の数に変換するときに無理が生じるので、負の数は負の数のまま扱うことにした。
#include <stdio.h> #include <string.h> #include <limits.h> int abs(int n); void reverse(char s[]); /* Answer */ void itoa(int n, char s[]) { int i, sign; sign = n; i = 0; do { s[i++] = abs(n % 10) + '0'; } while ((n /= 10) != 0); if (sign < 0) s[i++] = '-'; s[i] = '\0'; reverse(s); } int abs(int n) { return n < 0 ? -n : n; } void reverse(char s[]) { int c, i, j; for (i = 0, j = strlen(s) - 1; i < j; i++, j--) { c = s[i]; s[i] = s[j]; s[j] = c; } } int main(void) { int n; char s[100]; n = INT_MAX; itoa(n, s); printf("%d [%s]\n", n, s); n = INT_MIN; itoa(n, s); printf("%d [%s]\n", n, s); return 0; }