代码之家  ›  专栏  ›  技术社区  ›  Chris de Vries

防止算术溢出和下溢的最有效的一种方法

  •  1
  • Chris de Vries  · 技术社区  · 16 年前

    最有效的预防措施是什么 arithmetic overflow underflow ?

    我们想到的一些例子是:

    • 基于有效输入范围的测试
    • 使用正式方法进行验证
    • 不变量的使用
    • 在运行时使用语言功能或库进行检测(这不会阻止检测)
    7 回复  |  直到 13 年前
        1
  •  3
  •   Salman A    15 年前

    一种可能是使用具有任意大小的整数的语言,该整数永远不会溢出/下溢。

    否则,如果这是您真正关心的事情,并且您的语言允许的话,那么编写一个类似于整数的包装类,但是检查每个操作是否溢出。您甚至可以让它对调试版本进行检查,并为发布版本对其进行优化。在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的支持。

        2
  •  1
  •   itsmatt    16 年前

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

        3
  •  1
  •   postfuturist    16 年前

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

        4
  •  1
  •   Jörg W Mittag    16 年前

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

        5
  •  0
  •   pro3carp3    16 年前

    在选择使用哪种语言时,有比整数大小更重要的考虑因素。如果不知道值是否在界限内,只需检查输入,如果情况非常罕见,则使用异常处理。

        6
  •  0
  •   mturquette    15 年前

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

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

    同样,任何逻辑上会导致较小值的操作都应该进行检查,以查看它是否被意外地嵌入。

        7
  •  0
  •   Jay Abraham    13 年前

    您是否调查过使用正式方法检查代码以证明它没有溢出?一种称为抽象解释的正式方法技术可以检查软件的健壮性,以证明软件不会出现溢出、下溢、被零除、溢出或其他类似的运行时错误。它是一种数学技术,可以详尽地分析您的软件。这项技术是帕特里克·库肖特在20世纪70年代首创的,它成功地用于诊断阿里安5号火箭的溢流状况,溢流导致了运载火箭的毁坏。溢出是在将浮点数转换为整数时造成的。你可以找到更多关于这种技术的信息 here 而且还 Wikipedia .