单一最有效的做法,以防止算术溢出和下溢

时间:2008-09-17 01:25:11

标签: language-agnostic numbers overflow math

阻止arithmetic overflowunderflow的唯一最有效的做法是什么?

我想到的一些例子是:

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

7 个答案:

答案 0 :(得分: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...
};

编辑:

原来是某人doing this already for C++ - 目前的实现主要针对Visual Studio,但看起来他们也获得了对gcc的支持。

答案 1 :(得分:1)

我编写了很多测试代码来对代码进行范围/有效性检查。这往往会抓住大多数这类情况 - 并且肯定会帮助我编写更多防弹代码。

答案 2 :(得分:1)

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

答案 3 :(得分:1)

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

答案 4 :(得分:0)

选择使用的语言比整数的大小有更重要的考虑因素。如果您不知道值是否在边界内,只需检查您的输入,或者如果案例非常罕见,则使用异常处理。

答案 5 :(得分:0)

在许多情况下,检查不一致的包装器是有意义的。如果两个或多个整数上的加法运算(即加法或乘法)导致的值小于操作数,则表示出现了问题。每个添加剂操作都应该跟着,

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

同样,任何逻辑上应该导致较小值的操作都应检查是否意外嵌入。

答案 6 :(得分:0)

您是否已调查过使用正式方法检查代码以证明其没有溢出?称为抽象​​解释的形式化方法技术可以检查软件的稳健性,以证明您的软件不会受到溢出,下溢,除零,溢出或其他类似的运行时错误的影响。这是一种详尽分析您的软件的数学技术。这项技术是由Patrick Cousot在20世纪70年代开创的。它成功地用于诊断Arian 5火箭的溢流状况,其中溢流导致运载火箭的破坏。在将浮点数转换为整数时引起溢出。您可以在here以及Wikipedia上找到有关此技术的更多信息。