Причина специфического упорядочения деления и умножения в C ++ - PullRequest
3 голосов
/ 03 декабря 2009

Я на пороге портирования некоторого кода на С ++ на java, и я продолжаю сталкиваться с случаями, когда кто-то, кто это написал, делал следующее:

double c = (1.0/(a+1.0)*pow(b, a+1.0));
double d = (1./(integral(gamma, dmax)-integral(gamma, dmin)))*(integral(gamma+1, dmax)-integral(gamma+1, dmin));

Вместо:

double c = pow(b, a+1.0)/(a+1.0);
double d = (integral(gamma+1, dmax)-integral(gamma+1, dmin))/(integral(gamma, dmax)-integral(gamma, dmin));

Второе кажется намного понятнее, и если я не ошибаюсь в порядке операций в C ++, они должны делать то же самое. Есть ли основания делать первое, а не второе? Единственное, о чем я мог подумать, это какой-то странный случай с точностью.

Ответы [ 3 ]

6 голосов
/ 03 декабря 2009

Да, они одинаковы. Единственная причина, по которой я могу придумать, это математическая ясность: иногда, когда вы нормализуете количество, вы часто пишете:

answer = (1/total) * (some of it)

Например, интегральная теорема Коши часто пишется

f(a) = (1/(2*pi*i)) * integral(f(z)/(z-a), dz)
2 голосов
/ 03 декабря 2009

Если a остается неизменным, а b меняется (скажем, если ваш код находится в цикле и ясно, что a не меняется между двумя итерациями, например, потому что это переменная const) тогда исходная версия может выполняться быстрее, потому что умножение дешевле деления (при условии, что компилятор перемещает вычисление 1/... из цикла).

Это кажется ошибочной попыткой оптимизации, если в этом причина, но это не значит, что это не так.

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

1 голос
/ 03 декабря 2009

Да, они должны делать то же самое. Первоначальный автор мог воспроизводить уравнения, найденные где-то еще, где

...