K&R 练习 3-4:用二进制表示的负数
K&R Exercise 3-4: Negative Numbers Represented In Binary
我很难理解这个练习:
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 -(2^(wordsize-1)). Explain why not. Modify it to print that value correctly, regardless of the machine on which it runs.
这是 itoa 的原始样子:
void reverse(char s[], int n)
{
int toSwap;
int end = n-1;
int begin = 0;
while(begin <= end) // Swap the array in place starting from both ends.
{
toSwap = s[begin];
s[begin] = s[end];
s[end] = toSwap;
--end;
++begin;
}
}
// Converts an integer to a character string.
void itoa(int n, char s[])
{
int i, sign;
if ((sign = n) < 0)
n = -n;
i = 0;
do
{
s[i++] = n % 10 + '0';
} while ((n /= 10) > 0);
if (sign < 0)
s[i++] = '-';
s[i] = '[=10=]';
reverse(s, i);
}
我找到了这个答案,但我不明白解释:
http://www.stevenscs.com/programs/KR/$progs/KR-EX3-04.html
Because the absolute value of the largest negative number a word can hold is greater than that of the largest positive number, the statement early in iota that sets positive a negative number corrupts its value.
他们是说负数因为有符号比没有符号的正数包含更多的位数吗?为什么乘以 -1 会影响大负数的存储方式?
问题是,如果 n 是最大的负数,当你执行 n=-n 时你得到 0,因为你不能表示那么大的正数。
一个解决方案是将正数保存在一个长整数中。
在补码表示中,你可以表示的取值范围是-2<sup>n-1</sup>
到2 <sup>n-1</sup>-1
。因此,使用 8 位,您可以表示 -128 到 127 范围内的值。这就是短语 "the largest negative number a word can hold is greater than that of the largest positive number."
的含义
仅用 3 位进行说明以使其更清晰:
Value Bits
----- ----
0 000
1 001
2 010
3 011
-4 100
-3 101
-2 110
-1 111
用 3 位,我们无法用二进制补码表示 正数 4
,所以 n = -n;
不会给我们结果期待1。这就是为什么上面的原始 atoi
实现无法处理 INT_MIN
.
- 有符号整数溢出的行为是未定义,这意味着没有固定的结果。
我很难理解这个练习:
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 -(2^(wordsize-1)). Explain why not. Modify it to print that value correctly, regardless of the machine on which it runs.
这是 itoa 的原始样子:
void reverse(char s[], int n)
{
int toSwap;
int end = n-1;
int begin = 0;
while(begin <= end) // Swap the array in place starting from both ends.
{
toSwap = s[begin];
s[begin] = s[end];
s[end] = toSwap;
--end;
++begin;
}
}
// Converts an integer to a character string.
void itoa(int n, char s[])
{
int i, sign;
if ((sign = n) < 0)
n = -n;
i = 0;
do
{
s[i++] = n % 10 + '0';
} while ((n /= 10) > 0);
if (sign < 0)
s[i++] = '-';
s[i] = '[=10=]';
reverse(s, i);
}
我找到了这个答案,但我不明白解释: http://www.stevenscs.com/programs/KR/$progs/KR-EX3-04.html
Because the absolute value of the largest negative number a word can hold is greater than that of the largest positive number, the statement early in iota that sets positive a negative number corrupts its value.
他们是说负数因为有符号比没有符号的正数包含更多的位数吗?为什么乘以 -1 会影响大负数的存储方式?
问题是,如果 n 是最大的负数,当你执行 n=-n 时你得到 0,因为你不能表示那么大的正数。
一个解决方案是将正数保存在一个长整数中。
在补码表示中,你可以表示的取值范围是-2<sup>n-1</sup>
到2 <sup>n-1</sup>-1
。因此,使用 8 位,您可以表示 -128 到 127 范围内的值。这就是短语 "the largest negative number a word can hold is greater than that of the largest positive number."
仅用 3 位进行说明以使其更清晰:
Value Bits
----- ----
0 000
1 001
2 010
3 011
-4 100
-3 101
-2 110
-1 111
用 3 位,我们无法用二进制补码表示 正数 4
,所以 n = -n;
不会给我们结果期待1。这就是为什么上面的原始 atoi
实现无法处理 INT_MIN
.
- 有符号整数溢出的行为是未定义,这意味着没有固定的结果。