Как мне обрабатывать значения, близкие к нулю в C ++? - PullRequest
0 голосов
/ 15 октября 2018

Я пытаюсь закодировать итеративную функцию, которая принимает начальную

double t = /*formula 1*/;

и затем вычисляет

for (auto i = 0; i < bigNumber; ++i)
{
    temp = /*formula 2*/;
    t = t*temp;
}

. Это прекрасно работает, за исключением случаев, когда начальная tнастолько мал, что C ++ автоматически устанавливает его равным нулю (на самом деле он НЕ должен быть нулем).

Тогда, конечно, t всегда будет оставаться нулевым, так как мы умножаем его на себя, и в этом проблема.

Я попытался решить эту проблему, установив t равным какому-то очень маленькому, но ненулевому числу, в случае, если C ++ установило его на ноль, но это не работает, потому что тогда я получаюпротивоположная проблема, когда t в конечном счете взрывается, как только мы повторили это достаточно раз.

Как мне решить эту проблему?

Возможно, стоит упомянуть:

Первая формула (формула 1) включает в себя такие вещи, как exp(-verybignumber), а вторая формула включает такие вещи, как pow(i, -1), что означает, что она становится очень маленькой с более высокими итерациями.

1 Ответ

0 голосов
/ 15 октября 2018

Арифметика с плавающей точкой не тривиальна, как вы только что обнаружили.Это на самом деле не связано с C ++, но со стандартом IEEE 754.

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

В некоторых случаях это просто и, возможно, достаточно изменить масштаб входных данных.В других случаях, возможно, вам придется переосмыслить свои уравнения (шаги), чтобы избежать этого.

Иногда вы можете просто уйти, используя больший тип, например long double или даже __float128 (quad, check * 1011)* libquadmath ).

Другие решения заключаются в использовании чисел произвольной точности (используйте такие библиотеки, как GMP и MPFR ; не пытайтесь делать это самостоятельнокак начинающий) или даже символические вычисления.Все зависит от того, какую производительность вам требуется.

Обратите внимание, что при работе с арифметикой с плавающей запятой существует много других подводных камней.

...