1

防止算术上溢下溢的最有效做法是什么?

想到的一些例子是:

  • 基于有效输入范围的测试
  • 使用正式方法进行验证
  • 不变量的使用
  • 使用语言功能或库在运行时检测(这不会阻止它)
4

7 回答 7

3

一种可能性是使用一种具有任意大小整数且永不上溢/下溢的语言。

否则,如果这是您真正关心的事情,并且如果您的语言允许,请编写一个类似于整数的包装类,但会检查每个操作是否溢出。你甚至可以让它检查调试版本,并为发布版本优化。在像 C++ 这样的语言中,您可以做到这一点,它的行为几乎与发布版本的整数一样,但对于调试版本,您将获得完整的运行时检查。

class CheckedInt
{
private: 
    int Value;

public:
    // Constructor
    CheckedInt(int src) : Value(src) {}

    // Conversions back to int
    operator int&() { return Value; }
    operator const int &() const { return Value; }

    // Operators
    CheckedInt operator+(CheckedInt rhs) const
    {
        if (rhs.Value < 0 && rhs.Value + Value > Value)
            throw OverflowException();
        if (rhs.Value > 0 && rhs.Value + Value < Value)
            throw OverflowException();
        return CheckedInt(rhs.Value + Value);
    }

    // Lots more operators...
};

编辑:

原来有人已经在为 C++ 做这件事了——当前的实现主要针对 Visual Studio,但看起来他们也正在获得对 gcc 的支持。

于 2008-09-17T01:28:33.577 回答
1

我编写了很多测试代码来对我的代码进行范围/有效性检查。这往往会捕捉到大多数这些类型的情况 - 并且绝对可以帮助我编写更多防弹代码。

于 2008-09-17T01:29:41.763 回答
1

使用高精度浮点数,如long double

于 2008-09-17T01:32:20.227 回答
1

我认为您的列表中缺少一个非常重要的选项:为工作选择正确的编程语言。有许多编程语言没有这些问题,因为它们没有固定大小的整数。

于 2008-09-17T01:49:26.070 回答
0

在选择使用哪种语言时,除了整数的大小之外,还有更重要的考虑因素。如果您不知道该值是否在界限内,只需检查您的输入,或者如果这种情况极为罕见,请使用异常处理。

于 2008-09-17T02:55:19.890 回答
0

在许多情况下,检查不一致的包装器是有意义的。如果对两个或多个整数的加法运算(即加法或乘法)产生的值小于操作数,那么您就知道出了问题。每个加法运算都应遵循,

if (sum < operand1 || sum < operand2)
    omg_error();

同样,应该检查逻辑上应该导致较小值的任何操作,以查看它是否被意外embiggin'd。

于 2009-06-22T16:31:42.753 回答
0

您是否调查过使用形式方法来检查您的代码以证明它没有溢出?一种称为抽象解释的形式方法技术可以检查软件的稳健性,以证明您的软件不会遭受上溢、下溢、被零除、上溢或其他类似的运行时错误。它是一种数学技术,可以详尽地分析您的软件。该技术由 Patrick Cousot 在 1970 年代首创。它成功地用于诊断阿里安 5 号火箭的溢出情况,溢出导致运载火箭损坏。将浮点数转换为整数时导致溢出。您可以在此处以及在Wikipedia上找到有关此技术的更多信息。

于 2012-02-10T20:38:43.153 回答