Единственный наиболее эффективный способ предотвращения арифметического переполнения - PullRequest
1 голос
/ 17 сентября 2008

Какая самая эффективная практика для предотвращения арифметического переполнения и недостаточного ?

Вот некоторые примеры, которые приходят на ум:

  • тестирование на основе допустимых диапазонов ввода
  • проверка с использованием формальных методов
  • использование инвариантов
  • обнаружение во время выполнения с использованием языковых функций или библиотек (это не мешает этому)

Ответы [ 7 ]

3 голосов
/ 17 сентября 2008

Одной из возможностей является использование языка с произвольными целыми числами, который никогда не переполняется / не переполняется.

В противном случае, если вас это действительно беспокоит, и если ваш язык это позволяет, напишите класс-оболочку, который действует как целое число, но проверяет каждую операцию на переполнение. Вы могли бы даже сделать так, чтобы он проверял отладочные сборки и оставлял вещи оптимизированными для сборок релизов. На таком языке, как 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...
};

Edit:

Оказывается, кто-то делает это уже для C ++ - текущая реализация ориентирована на Visual Studio, но похоже, что они также получают поддержку для gcc.

1 голос
/ 17 сентября 2008

Я думаю, вам не хватает одного очень важного параметра в вашем списке: выберите правильный язык программирования для работы. Есть много языков программирования, у которых нет этих проблем, потому что у них нет целых чисел фиксированного размера.

1 голос
/ 17 сентября 2008

Используйте высокоточные числа с плавающей запятой, такие как long double .

1 голос
/ 17 сентября 2008

Я пишу много тестового кода для проверки диапазона / достоверности моего кода. Это имеет тенденцию отлавливать большинство подобных ситуаций - и, безусловно, помогает мне писать более пуленепробиваемый код.

0 голосов
/ 11 февраля 2012

Вы исследовали использование формальных методов для проверки кода, чтобы убедиться, что он не переполнен? Метод формальных методов, известный как абстрактная интерпретация, может проверить надежность вашего программного обеспечения, чтобы доказать, что ваше программное обеспечение не будет страдать от переполнения, недостаточного заполнения, деления на ноль, переполнения или других подобных ошибок времени выполнения. Это математический метод, который тщательно анализирует ваше программное обеспечение. Техника была впервые разработана Патриком Кузо в 1970-х годах. Он был успешно использован для диагностики состояния переполнения в ракете Arian 5, где переполнение вызвало разрушение ракеты-носителя. Переполнение было вызвано при преобразовании числа с плавающей запятой в целое число. Вы можете найти больше информации об этой технике здесь , а также в Wikipedia .

0 голосов
/ 22 июня 2009

Оболочка, которая проверяет несоответствия, будет иметь смысл во многих случаях. Если аддитивная операция (т.е. сложение или умножение) с двумя или более целыми числами приводит к меньшему значению, чем операнды, то вы знаете, что что-то пошло не так. За каждой аддитивной операцией должно следовать,

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

Аналогично, любая операция, которая должна логически привести к меньшему значению, должна быть проверена, чтобы убедиться, что она была случайно вставлена.

0 голосов
/ 17 сентября 2008

При выборе языка, который вы используете, важнее, чем размер целого числа. Просто проверьте свой ввод, если вы не знаете, находится ли значение в границах, или используйте обработку исключений, если случай крайне редкий.

...