我的C-Program执行" Turmrechnung"(预定义数字(" init_num"乘以预定义的数字范围)(init_num * 2 * 3 * 4 * 5 * 6 * 7 * 8 * 9在我的情况下,由变量" h")定义,之后它除以那些相同的数字,结果应该是" init_num&#34的初始值如果init_num的值大于INT_MAX(来自limits.h),我的任务是集成一种停止计算的方法。 但是,如果" init_num"的初始值较大,那么If-Statement总是正确的,即使它不是,这会导致沿计算方式的值大于INT_MAX。
只有当我更换" INT_MAX"我的If-Statement中的数字小于INT_MAX,如200000000。为什么呢?
#include <limits.h>
#include <stdio.h>
int main() {
int init_num = 1000000;
int h = 9;
for (int i = 2; i < h+1; ++i)
{
if (init_num * i < INT_MAX)
{
printf("%10i %s %i\n", init_num, "*", i);
init_num *= i;
}
else
{
printf("%s\n","An overflow has occurred!");
break;
}
}
for (int i = 2; i < h+1; ++i)
{
printf("%10i %s %i\n", init_num, ":", i);
init_num /= i;
}
printf("%10i\n", init_num);
}
答案 0 :(得分:5)
template<typename T, typename N>
typename std::enable_if<std::is_arithmetic<T>::value,N>::type
cast(const T& source) const {
return static_cast<N>(source);
}
if (init_num * i < INT_MAX)
是INT_MAX
的最大值,因此,此条件永远不会 false 或换句话说int
(除外等于0
)。
如果你想要,你可以写下这样的条件 -
INT_MAX
答案 1 :(得分:2)
问题是签名整数溢出是未定义的行为。专注于“未定义”部分并思考它。简而言之:在任何情况下都要避免。
为了避免这种情况,你可以使用一个更宽的类型来保证乘法的结果,然后进行测试:
// ensure the type we use for cast is large enough
_Static_assert(LLONG_MAX > INT_MAX, "LLONG too small.");
if ( (long long)init_num * i < (long long)INT_MAX )
这显然不起作用,你已经处于极限(即使用最大的数据类型)。所以你必须提前检查:
if ( init_num < (INT_MAX / i) ) {
init_num *= i;
虽然由于额外划分而耗费更多时间,但这通常是更好的方法,因为它不需要更大的数据类型(乘法可能也更昂贵)。
答案 2 :(得分:1)
init_num * i < INT_MAX
int_num * i
,则 INT_MAX
只会为0。这不太可能。请注意,有符号整数溢出在C中是未定义的行为,所以在这里要特别小心。
您可以在特定情况下将语句重写为init_num < INT_MAX / i
。请注意,整数除法会截断。
答案 3 :(得分:0)
awk -F " " '{
print $1" " $2" "$3" "$4" "$5" "$6" "$7" "'32.450'" "$9" "$10"
}' input.pdb > output.pdb
会产生init_num * int
,但通过定义不能超过最大可能int
(int
)。
所以提供&#34;房间&#34;用于计算&#34;更大&#34;通过替换
而不是INT_MAX
int
与
if (init_num * i < INT_MAX)
转换为if ((long) init_num * i < (long) INT_MAX)
会产生long
结果。
(上述方法假设long
比long
更宽。)