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

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

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 в Java?
  • Как анализировать float с двумя десятичными знаками в javascript?
  • Почему арифметика с плавающей запятой в C # неточна?
  • C: Как поместить float на интервал [-pi, pi)
  • Почему мы не можем использовать '==' для сравнения двух чисел с плавающей запятой или двойных чисел
  • Почему бы не использовать Double или Float для представления валюты?
  • Разница в арифметике с плавающей запятой между x86 и x64
  • Когда следует использовать double вместо десятичного?
  • Какой диапазон чисел может быть представлен в 16-, 32- и 64-битных системах IEEE-754?
  • Детали реализации оборудования с плавающей запятой
  • Формат Float до n знаков после запятой
  • Давайте будем гением компьютера.