Неправильная математика с плавающей точкой? - PullRequest
2 голосов
/ 06 августа 2009

Вот проблема, которая меня совершенно сбила с толку в течение последних нескольких часов ...

В моей программе жестко запрограммировано уравнение:

double s2;

s2 = -(0*13)/84+6/42-0/84+24/12+(6*13)/42;

Каждый раз, когда я запускаю программу, компьютер выдает 3 в качестве ответа, однако, делая математику вручную, я получаю 4. Еще дальше, после ввода уравнения в Matlab, я также получаю ответ 4. Что происходит здесь

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

Кто-нибудь может предложить какие-либо решения?

Заранее спасибо,

-Faken

Ответы [ 4 ]

17 голосов
/ 06 августа 2009

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

В C ++ 5/4 = 1, не 1.25 - потому что 5 и 4 являются целыми числами, поэтому результат будет целым числом, и, следовательно, дробная часть результата будет отброшена.

С другой стороны, 5.0 / 4.0 будет равен ок. 1.25, потому что по крайней мере один из 5.0 и 4.0 является числом с плавающей точкой, поэтому результат также будет с плавающей точкой.

7 голосов
/ 06 августа 2009

Вы путаете целочисленное деление с делением с плавающей запятой. 3 - правильный ответ с целочисленным делением. Вы получите 4, если конвертируете эти значения в числа с плавающей запятой.

3 голосов
/ 06 августа 2009
s2 = -(0*13)/84+6/42-0/84+24/12+(6*13)/42;

дает 3

s2 = -(0.*13.)/84.+6./42.-0./84.+24./12.+(6.*13.)/42.;

делает то, что вы ожидаете.

3 голосов
/ 06 августа 2009

Часть этого оценивается с помощью целочисленной арифметики. Попробуйте добавить к своим числам десятичную точку, например, 6.0 вместо 6, чтобы сообщить компилятору, что вам не нужна целочисленная арифметика.

...