Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/66.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在C语言中检测整数溢出_C_Overflow - Fatal编程技术网

如何在C语言中检测整数溢出

如何在C语言中检测整数溢出,c,overflow,C,Overflow,我们知道当数字变大时,CPython会将整数提升为长整数(允许任意精度的算术) 如何在纯C中检测int和long溢出?您无法检测有符号int溢出。您必须编写代码来避免它 有符号整数溢出是未定义的行为,如果它存在于您的程序中,则该程序无效,并且不需要编译器生成任何特定行为。您无法检测有符号的int溢出。您必须编写代码来避免它 有符号整数溢出是未定义的行为,如果它存在于您的程序中,则该程序无效,并且编译器不需要生成任何特定行为。您可以预测有符号整数溢出,但尝试在求和后检测它为时已晚。在执行签名加法之

我们知道当数字变大时,CPython会将整数提升为长整数(允许任意精度的算术)

如何在纯C中检测
int
long
溢出?

您无法检测有符号
int
溢出。您必须编写代码来避免它

有符号整数溢出是未定义的行为,如果它存在于您的程序中,则该程序无效,并且不需要编译器生成任何特定行为。

您无法检测有符号的
int
溢出。您必须编写代码来避免它


有符号整数溢出是未定义的行为,如果它存在于您的程序中,则该程序无效,并且编译器不需要生成任何特定行为。

您可以预测有符号整数溢出,但尝试在求和后检测它为时已晚。在执行签名加法之前,必须测试可能的溢出

在求和后通过测试来避免未定义的行为是不可能的。如果添加溢出,则已经存在未定义的行为

如果是我,我会这样做:

#include <limits.h>

int safe_add(int a, int b) 
{
    if (a >= 0) {
        if (b > (INT_MAX - a)) {
            /* handle overflow */
        }
    } else {
        if (b < (INT_MIN - a)) {
            /* handle underflow */
        }
    }
    return a + b;
}
访问这个

编辑:

关于某人提出的问题


我认为,解释为什么有符号整数溢出未定义,而无符号溢出显然未定义,这将是一件非常好的事情

答案取决于编译器的实现。大多数C实现(编译器)只是使用它所使用的整数表示法来实现最容易实现的溢出行为


实际上,有符号值的表示可能不同(根据实现):
一个补码
两个补码
符号幅度
。对于无符号类型,标准没有理由允许变化,因为只有一种明显的
二进制表示法
(标准只允许二进制表示法)。

您可以预测
有符号整数溢出
,但尝试在求和后检测它为时已晚。在执行签名加法之前,必须测试可能的溢出

在求和后通过测试来避免未定义的行为是不可能的。如果添加溢出,则已经存在未定义的行为

如果是我,我会这样做:

#include <limits.h>

int safe_add(int a, int b) 
{
    if (a >= 0) {
        if (b > (INT_MAX - a)) {
            /* handle overflow */
        }
    } else {
        if (b < (INT_MIN - a)) {
            /* handle underflow */
        }
    }
    return a + b;
}
访问这个

编辑:

关于某人提出的问题


我认为,解释为什么有符号整数溢出未定义,而无符号溢出显然未定义,这将是一件非常好的事情

答案取决于编译器的实现。大多数C实现(编译器)只是使用它所使用的整数表示法来实现最容易实现的溢出行为


实际上,有符号值的表示可能不同(根据实现):
一个补码
两个补码
符号幅度
。对于无符号类型,标准没有理由允许变化,因为只有一种明显的
二进制表示形式
(标准仅允许二进制表示形式)。

在执行加法之前,必须测试有符号操作数。这是一个安全的加法函数,在所有情况下都有两个比较:

#include <limits.h>

int safe_add(int a, int b) {
    if (a >= 0) {
        if (b > INT_MAX - a) {
            /* handle overflow */
        } else {
            return a + b;
        }
    } else {
        if (b < INT_MIN - a) {
            /* handle negative overflow */
        } else {
            return a + b;
        }
    }
}

在执行加法之前,必须测试有符号操作数。这是一个安全的加法函数,在所有情况下都有两个比较:

#include <limits.h>

int safe_add(int a, int b) {
    if (a >= 0) {
        if (b > INT_MAX - a) {
            /* handle overflow */
        } else {
            return a + b;
        }
    } else {
        if (b < INT_MIN - a) {
            /* handle negative overflow */
        } else {
            return a + b;
        }
    }
}

这是非常棘手的,因为您无法添加两个数字并检查值是否高于某个阈值(因为有符号整数算术溢出等等)。一个简单的解决方案可能是检查
x
(要检查的值)是否高于特定阈值,或者添加一个值是否高于阈值。如果是这样,并且您要添加的另一个数字大于1,那么您就出现了溢出情况。吹毛求疵,但是,是CPython 2.7做到了这一点。CPython 3不会“升级”任何内容,即使在内部只有一种类型。根据您对值的处理方式(add/sub/mul/div/…),会有很多重复项(add/sub/mul/div/…),再添加1。这非常棘手,因为您无法添加两个数字并检查值是否高于某个阈值(因为有符号整数算术溢出等). 一个简单的解决方案可能是检查
x
(要检查的值)是否高于特定阈值,或者添加一个值是否高于阈值。如果是这样,并且您要添加的另一个数字大于1,那么您就出现了溢出情况。吹毛求疵,但是,是CPython 2.7做到了这一点。CPython 3不会“升级”任何东西,即使在内部只有一种类型。根据您想对值执行的操作(add/sub/mul/div/…),会有很多重复项,再添加1个,您可以在进行计算之前检查输入值以防止溢出。我想,解释一下为什么有符号整数溢出未定义,而无符号溢出显然没有定义,这将是一件非常有益的事情。@Heteperfan这是因为语言标准是这么说的。@sneftel这是一个缺乏权威来源的权威论点,尽管它可能是正确的。最重要的是,一旦人们开始理解语言,标准对他们来说就更有意义,这可能是他们首先访问stackoverflow的原因。@Heteperfan解释了标准按原样编写的原因,在很大程度上超出了堆栈溢出的范围。在进行计算之前,您可以检查输入值以防止溢出。我认为,解释为什么未定义有符号整数溢出是一件非常有益的事情,然而unsigned显然不是…@heteperfan,这是因为语言标准是这么说的。@snetel这是一个缺乏权威来源的权威论点,轻视它可能是正确的。最重要的是,一旦人们开始理解,标准对他们来说就更有意义了