Полезно ли иметь промежуточные результаты в двойных числах, когда ввод и вывод являются числами с плавающей запятой?

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

float performSomeComputations(float value)
{
    // addition, substraction, logarithms, multiplication, etcetera
    float a = value * 12.0;
    float b = math.pow(a, 34.0);
    float c = math.log10(b +  value - 567);
    return a + b + c;
}

Мой вопрос: имеет ли значение, как вы храните промежуточные результаты? т.е. как float или как double? Предположим, что промежуточные значения не превышают минимальное и/или максимальное значение, тогда очевидно будет разница. Но будет ли возвращаемое значение более точным, если используются типы double, или вы всегда будете получать один и тот же ответ после того, как он, наконец, вернется к float? И возможно ли, что ответ может варьироваться в зависимости от языка программирования?


person Yellow    schedule 08.10.2013    source источник


Ответы (1)


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

Если расчеты и цифры таковы, что точность промежуточных результатов несколько выше, возможно, конечный результат все равно будет таким же. Но так будет не всегда; в некоторых случаях, особенно при сложных вычислениях, требующих много шагов, окончательный результат будет более точным, поскольку на каждом шаге происходит меньшая потеря точности.

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

person Roy Dictus    schedule 08.10.2013
comment
Очевидно, что результат будет по крайней мере таким же точным с doubles, но если это не имеет значения, зачем возиться со всеми кастингами? Не могли бы вы привести пример случая, когда это действительно имеет значение? - person Yellow; 08.10.2013
comment
если есть сложные вычисления, которые занимают много шагов... Это может привести к потере точности на каждом шаге, но в меньшей степени, когда промежуточные результаты будут более точными. - person Roy Dictus; 08.10.2013
comment
Достаточно справедливо, но, в конце концов, промежуточное звено double будет преобразовано в float, так что дополнительная точность снова будет потеряна. Итак, как вы можете быть уверены, что не вся дополнительная точность всегда будет потеряна на этом этапе? Другими словами, как вы можете быть уверены, что double промежуточные продукты стоят того? - person Yellow; 08.10.2013