Величина наименьшего нормального числа IEEE с одинарной точностью составляет около 1,18e-38, а наименьшая денормализация сводит вас к 1,40e-45.Как следствие, операнд величиной 7,82e-43 будет содержать только около 9 ненулевых битов, что само по себе может быть проблемой, даже до того, как вы перейдете к умножению (результат которого опустится до нуля с одинарной точностью).Таким образом, вы можете также захотеть взглянуть на любые вычисления в восходящем направлении, которые производят эти крошечные числа.
Если эти небольшие числа являются промежуточными терминами в математическом выражении, переписайте это выражение в математически эквивалентное, которое не включает крошечныепромежуточные звенья будут одним из способов решения проблемы.Или вы можете масштабировать некоторые операнды с помощью коэффициентов, равных двум степеням (чтобы избежать дополнительного округления из-за масштабирования).Например, масштабировать до 2 ^ 24 = 16777216.
Наконец, вы можете переключить часть вычисления на двойную точность.Для этого просто введите временные переменные типа double, выполните для них вычисления, а затем преобразуйте конечный результат обратно в float:
float r, f = 7.721155e-43f;
double d, t;
d = (double)f; // explicit cast is not necessary, since converting to wider type
t = d * d;
[... more intermediate computation, leaving result in 't' ...]
r = (float)t; // since conversion is to narrower type, cast will avoid warnings