可以是“价值”吗?溢出? [英] Can a "value" overflow?
问题描述
您好,任何人都可以解释为什么以下功能不起作用
INT_MIN:
/ * itoa:将n转换为s * /
中的字符
void itoa(int n,char s [])
{
int i,sign;
if ((sign = n)< 0)/ *记录标志* /
n = -n; / * make n positive * /
i = 0;
do / *生成相反顺序的数字* /
{
s [i ++] = n%10 +''0''; / *得到下一个数字* /
} while((n / = 10)> 0); / *删除它* /
if(sign< 0)
s [i ++] ='' - '';
>
s [i] =''\ 0'';
reverse(s); / *另一个功能;与我的问题无关* /
}
我把它缩小到n = -n行。在我的机器上, - (INT_MIN)
比INT_MAX多1。这会溢出临时值
-n,还是实际对象n。我想要问的是,当故障发生了吗?
我的感觉是错误(未定义的行为)首先发生在
-n,因为结果的值是signed int(没有促销
或转换),并且该值溢出。这有意义吗?
可以重视吗?溢出就像对象一样?
有没有人知道如何修复这个函数以允许它接受任何
整数参数(包括2'的INT_MIN)补充机器)?
Hello, can anyone explain why the following function will not work for
INT_MIN:
/* itoa: convert n to characters in s */
void itoa(int n, char s[])
{
int i, sign;
if((sign = n) < 0) /* record sign */
n = -n; /* make n positive */
i = 0;
do /* generate digits in reverse order */
{
s[i++] = n % 10 + ''0''; /* get next digit */
} while ((n /= 10) > 0); /* delete it */
if (sign < 0)
s[i++] = ''-'';
s[i] = ''\0'';
reverse(s); /* another function; irrelevant to my question */
}
I''ve narrowed it down to the n = -n line. On my machine, -(INT_MIN)
would be 1 more than INT_MAX. Does this overflow the temporary value
-n, or the actual object n. What I''m trying to ask is, when the fault
happens?
My feeling is that the fault (undefined behaviour) first occurs with
the -n, because the value of the result is a signed int (no promotions
or conversions) and that value is overflowed. Does that make sense?
Can a "value" overflow just like objects can?
Does anyone know how to fix this function to allow it to accept any
integer argument (including INT_MIN on 2''s complement machines)?
推荐答案
TTroy写道:
您好,任何人都可以解释为什么以下功能会不工作INT_MIN
:
/ * itoa:将n转换为s * /
中的字符void itoa(int n,char s [])
{<如果((sign = n)< 0)/ *记录符号* /
n = -n; / *使n为正* /
i = 0;
以/ *生成相反顺序的数字* /
{
s [i ++] = n%10 +''0''; / *得到下一个数字* /
} while((n / = 10)> 0); / *删除它* /
if(sign< 0)
s [i ++] ='' - '';
s [i] =' '\0'';
反向; / *另一个功能;与我的问题无关* /
}
我把它缩小到n = -n行。在我的机器上, - (INT_MIN)
比INT_MAX多1。这会溢出临时值
-n还是实际对象n。我想要问的是,当
故障发生时?
我的感觉是错误(未定义的行为)首先发生在-n,因为结果的值是一个signed int(没有
促销或转换),并且该值溢出。这有意义吗?
可以重视吗?溢出就像对象一样?
有谁知道如何修复这个函数以允许它接受任何
整数参数(包括2'补码机上的INT_MIN)?
Hello, can anyone explain why the following function will not work for INT_MIN:
/* itoa: convert n to characters in s */
void itoa(int n, char s[])
{
int i, sign;
if((sign = n) < 0) /* record sign */
n = -n; /* make n positive */
i = 0;
do /* generate digits in reverse order */
{
s[i++] = n % 10 + ''0''; /* get next digit */
} while ((n /= 10) > 0); /* delete it */
if (sign < 0)
s[i++] = ''-'';
s[i] = ''\0'';
reverse(s); /* another function; irrelevant to my question */
}
I''ve narrowed it down to the n = -n line. On my machine, -(INT_MIN)
would be 1 more than INT_MAX. Does this overflow the temporary value
-n, or the actual object n. What I''m trying to ask is, when the fault happens?
My feeling is that the fault (undefined behaviour) first occurs with
the -n, because the value of the result is a signed int (no promotions or conversions) and that value is overflowed. Does that make sense?
Can a "value" overflow just like objects can?
Does anyone know how to fix this function to allow it to accept any
integer argument (including INT_MIN on 2''s complement machines)?
值也有类型。所以-n是一个表达式,它解析为signed int类型的
值。您输入的最大容量为$ / b $ b,因此未定义行为。
试试这个:
void itoa(int n,char s []){
int i,sign;
sign = n;
i = 0;
做{
s [i ++] = abs(n%10)+''0'';
} while(n / = 10);
if(sign< 0)
s [i ++] ='' - '';
s [i] =''\ 0'';
reverse(s);
}
在上面的示例中,没有溢出。我仍然认为有一个问题,尽管大多数计算机都会表现正常:n%的结果是b%b是实现定义的,因为n可能是负数(但任何理智
编译器将产生大多数人期望的结果。
预计任何良好实施的结果如-18%10 = 8。
>
TTroy写道:
您好,任何人都可以解释为什么以下函数不能用于INT_MIN
:
- 从KnR2,第64页抓取itoa()。 -
我已将其缩小到n = -n行。在我的机器上, - (INT_MIN)
比INT_MAX多1。这会溢出临时值
-n还是实际对象n。我想要问的是,当
故障发生时?
我的感觉是错误(未定义的行为)首先发生在-n,因为结果的值是一个signed int(没有
促销或转换),并且该值溢出。这有意义吗?
可以重视吗?溢出就像对象一样吗?
有谁知道如何修复这个函数以允许它接受任何
整数参数(包括2'补码机上的INT_MIN)?
难道这不是KnR2,练习3-4吗?
基本上,你是对的,两个'补充,
的绝对值INT_MIN比INT_MAX大一个。因此,设置int i = INT_MIN
* -1;导致溢出(两个补码)。
在上面的itoa函数中,
执行/ *生成相反顺序的数字* /
{
s [i ++] = n%10 +''0''; / *得到下一个数字* /
} while((n / = 10)> 0); / *删除它* /
运行一次,然后while循环结束,因为n仍然是负的
,因为溢出。
添加'' - '':
if(sign< 0)
s [i ++] ='' - '';
Hello, can anyone explain why the following function will not work for INT_MIN:
-- Snip itoa() from KnR2, pg 64. --
I''ve narrowed it down to the n = -n line. On my machine, -(INT_MIN)
would be 1 more than INT_MAX. Does this overflow the temporary value
-n, or the actual object n. What I''m trying to ask is, when the fault happens?
My feeling is that the fault (undefined behaviour) first occurs with
the -n, because the value of the result is a signed int (no promotions or conversions) and that value is overflowed. Does that make sense?
Can a "value" overflow just like objects can?
Does anyone know how to fix this function to allow it to accept any
integer argument (including INT_MIN on 2''s complement machines)?
Isn''t this straight out of KnR2, Exercise 3-4?
Basically, you''re right, in two''s complement, the absolute value of
INT_MIN is one greater than INT_MAX. Therefore, setting int i = INT_MIN
* -1; results in overflow (in two''s complement).
In the itoa function above,
do /* generate digits in reverse order */
{
s[i++] = n % 10 + ''0''; /* get next digit */
} while ((n /= 10) > 0); /* delete it */
runs once, and then the while loop ends because n is still negative
because of the overflow.
The ''-'' is added:
if (sign < 0)
s[i++] = ''-'';
然后字符串终止并反转。
有很多方法可以编写这个函数,你只需要明确地捕获INT_MIN的
情况,例如:
如果(n == INT_MIN)/ *做某事以防止溢出* /
或暗示以某种方式转换将INT_MIN转换成安全的东西
分配成一个整数。
and then the string is terminated and reversed.
There are many ways to write this function, you just have to catch the
case of INT_MIN, either explicitly, e.g.:
if(n == INT_MIN) /* do something to prevent overflow */
or implicitly in a way that converts the INT_MIN into something safe to
assign into an integer.
有谁知道如何修复此函数以允许它接受任何
整数参数(包括2'补码机上的INT_MIN)?
Does anyone know how to fix this function to allow it to accept any
integer argument (including INT_MIN on 2''s complement machines)?
你可能会有为INT_MIN生成特殊异常,或者
修改你的算法thm。
溢出发生在值本身,因此在将其存储在变量中之前使用
它不能保存它(我认为这就是你所要求的。)
然而,一个更好的方法可能是不采取绝对的
值。只需将它作为负面使用,并改变你的时间为(b / b)!= 0)
Jon
----
学习使用Linux汇编语言编程
http://www.cafeshops.com/bartlettpublish.8640017
这篇关于可以是“价值”吗?溢出?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!