Как обнаружить переполнение и переполнение двойной точки с двойной точностью?

У меня есть следующие переменные:

double dblVar1; double dblVar2; 

Они могут иметь большие значения, но не более double макс.

У меня есть различная арифметика над такими переменными, как сложение, умножение и мощность:

 double dblVar3 = dblVar1 * dblVar2; double dblVar4 = dblVar1 + dblVar2; double dblVar5 = pow(dblVar1, 2); 

Во всем выше я должен проверить переполнение и недоиспользование. Как я могу достичь этого в C ++?

Многое зависит от контекста. Чтобы быть совершенно портативным, вы должны проверить перед операцией, например (для добавления):

 if ( (a < 0.0) == (b < 0.0) && std::abs( b ) > std::numeric_limits::max() - std::abs( a ) ) { // Addition would overflow... } 

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

Если все компьютеры, на которые настроена таргетинг, поддерживают IEEE (что, вероятно, имеет место, если вам не нужно учитывать мэйнфреймы), вы можете просто выполнять операции, а затем использовать isfinite или isinf для результатов.

Для нижнего streamа первый вопрос заключается в том, считается ли постепенное недоисполнение недостаточным или нет. Если нет, то просто проверьте, равны ли результаты, а a != -b выполнит трюк. Если вы хотите обнаружить постепенное переполнение (возможно, только в том случае, если у вас есть IEEE), вы можете использовать isnormal – это вернет false, если результаты соответствуют постепенному переполнению. (В отличие от переполнения, после операции вы проверяете «underflow»).

POSIX, C99, C ++ 11 имеют для C ++ 11), которые имеют функции для проверки флажков исключений IEEE754 (которые не имеют ничего общего с исключениями C ++, это было бы слишком просто) :

 int feclearexcept(int); int fegetexceptflag(fexcept_t *, int); int feraiseexcept(int); int fesetexceptflag(const fexcept_t *, int); int fetestexcept(int); 

Флаг является битовым полем со следующими битами:

 FE_DIVBYZERO FE_INEXACT FE_INVALID FE_OVERFLOW FE_UNDERFLOW 

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

С достойным компилятором (который поддерживает новейший стандарт C ++) вы можете использовать следующие функции:

 #include  #include  int main() { std::feclearexcept(FE_OVERFLOW); std::feclearexcept(FE_UNDERFLOW); double overflowing_var = 1000; double underflowing_var = 0.01; std::cout << "Overflow flag before: " << (bool)std::fetestexcept(FE_OVERFLOW) << std::endl; std::cout << "Underflow flag before: " << (bool)std::fetestexcept(FE_UNDERFLOW) << std::endl; for(int i = 0; i < 20; ++i) { overflowing_var *= overflowing_var; underflowing_var *= underflowing_var; } std::cout << "Overflow flag after: " << (bool)std::fetestexcept(FE_OVERFLOW) << std::endl; std::cout << "Underflow flag after: " << (bool)std::fetestexcept(FE_UNDERFLOW) << std::endl; } /** Output: Overflow flag before: 0 Underflow flag before: 0 Overflow flag after: 1 Underflow flag after: 1 */ 

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

Это обеспечивает

 FE_INEXACT FE_DIVBYZERO FE_UNDERFLOW FE_OVERFLOW FE_INVALID 

Например

  { double f; int raised; feclearexcept (FE_ALL_EXCEPT); f = compute (); raised = fetestexcept (FE_OVERFLOW | FE_INVALID); if (raised & FE_OVERFLOW) { /* ... */ } if (raised & FE_INVALID) { /* ... */ } /* ... */ } 

http://www.gnu.org/software/libc/manual/html_node/Status-bit-operations.html

  • Сколько значимых цифр имеет float и double в java?
  • Java двойное сравнение epsilon
  • Является ли плавающая точка == когда-либо ОК?
  • Должен ли я использовать double или float?
  • Как преобразовать float в int с Java
  • Могут ли какие-либо процессоры реального мира не использовать IEEE 754?
  • Float / double precision в режимах отладки / выпуска
  • Типы с плавающей запятой с фиксированным размером
  • Что означают F и D в конце числовых литералов?
  • Двойной расчет, создающий нечетный результат
  • Когда следует использовать ключевое слово "strictfp" в java?
  • Interesting Posts

    Что произойдет, если я использую RAM с более высокой скоростью, чем поддерживает процессор?

    Динамическое связывание Java и переопределение метода

    Не удается получить IP-адрес IPV6 с любым адаптером 802.11g

    Модификатор static разрешен только в объявлениях с постоянной переменной

    как обеспечить функцию подкачки для моего classа?

    Как установить Spannable object font с пользовательским шрифтом

    Загрузка файла ASP.NET MVC 3.0

    org.openqa.selenium.WebDriverException: неизвестная ошибка: файл DevToolsActivePort не существует при попытке запустить браузер Chrome

    См. Историю того, кто все открыл конкретный файл

    C ++ / Win32: Как дождаться завершения отложенного удаления?

    Является ли java.time неспособным анализировать долю секунды?

    Что такое ассоциативность операторов и почему это важно?

    Как настроить Windows с внешнего жесткого диска?

    dropdownlist задает выбранное значение в MVC3 Razor

    Где предложение IN в LINQ

    Давайте будем гением компьютера.