Я попадаю в ситуацию, когда вычисление 1.77e-308/10
вызывает исключение переполнения, но вычисление 1.777e-308/10
- нет. Это странно, потому что:
Недополнение происходит, когда истинный результат с плавающей запятой операция меньше по величине (т.е. ближе к нулю), чем наименьшее значение, представляемое как нормальное число с плавающей запятой в целевой тип данных (из Arithmetic Underflow, Wikipedia)
Другими словами, если мы вычисляем x/y
, где оба x
и y
равны double
, тогда нижнее течение должно происходить, если 0 < |x/y| < 2.2251e-308
(наименьшая положительная нормализованная double
равна 2.2251e-308
). Поэтому в теории как 1.77e-308/10
, так и 1.777e-308/10
должно возникать исключение underflow. Теория противоречит тому, что я тестировал с помощью программы C. ниже.
#include <stdio.h>
#include <fenv.h>
#include <math.h>
int main(){
double x,y;
// x = 1.77e-308 => underflow
// x = 1.777e-308 gives ==> no underflow
x=1.77e-308;
feclearexcept(FE_ALL_EXCEPT);
y=x/10.0;
if (fetestexcept(FE_UNDERFLOW)) {
puts("Underflow\n");
}
else puts("No underflow\n");
}
Чтобы скомпилировать программу, я использовал gcc program.c -lm
; Я также попробовал Клэнг, который дал мне тот же результат. Любое объяснение?
[Edits] Я разделил приведенный выше код через эту онлайн-среду IDE.