Проблема косинуса C ++ - PullRequest
       36

Проблема косинуса C ++

2 голосов
/ 21 сентября 2009

У меня есть следующий код с использованием C ++:

double value = .3;
double result = cos(value);

Когда я смотрю на значения в окне местных жителей на «значение», оно показывает 0.2999999999

Затем, когда я получаю значение «result», я получаю: 0.95533648912560598

Однако, когда я запускаю cos (.3) на калькуляторе компьютера, я получаю: .9999862922474

Так ясно, что я что-то не так делаю.

Есть мысли о том, что может быть причиной разницы в результатах?

Я использую Win XP на процессоре Intel.

Спасибо

Ответы [ 6 ]

20 голосов
/ 21 сентября 2009

Разница в результатах объясняется тем, что:

Калькулятор вашего компьютера возвращает косинус угла, указанного в градусах. Функция C ++ cos () возвращает косинус угла, указанного в радианах.

.2999999999 из-за способа обработки чисел с плавающей запятой в компьютерах. .3 не может быть представлен точно в двойном. Для подробностей я рекомендую прочитать Что должен знать каждый компьютерный специалист об арифметике с плавающей точкой.

10 голосов
/ 21 сентября 2009

cos (.3 радиана) = 0,95533 ...

cos (.3 градуса) = 0,99999 ...

4 голосов
/ 21 сентября 2009

cos (0.3) = 0.99998629224742679269138848004408 с использованием градусов

cos (0,3) = 0,95533648912560601964231022756805 с использованием радианов

3 голосов
/ 21 сентября 2009

Когда я смотрю на значения в окне местных жителей на «значение», оно показывает 0,2999999999

Короче говоря, ваш калькулятор использует десятичную арифметику, а ваш код C ++ использует двоичную арифметику (double - это двоичное число с плавающей запятой). Десятичное число 0.3 не может быть представлено точно как двоичное число с плавающей точкой. Прочитайте Что должен знать каждый компьютерный ученый об арифметике с плавающей точкой , которая объяснит все последствия более подробно.

2 голосов
/ 21 сентября 2009

C ++ не совсем точно представляет числа с плавающей запятой из-за безумного объема памяти, который потребовался бы для получения необходимой бесконечной точности. Для демонстрации этого попробуйте следующее:

double ninth = 1.0/9.0;
double result = 9.0 * ninth;

Это должно привести к значению в результате .99999999999

Итак, по сути, вам нужно сравнить значения с плавающей запятой в небольшом эпсилоне (я склонен использовать 1e-7). Вы можете выполнить строгое побитовое сравнение, но оно состоит из преобразования памяти, используемой с плавающей запятой, в массив символов длины sizeof (float), а затем сравнения символов.

Еще одна вещь, которую нужно проверить, это то, используете ли вы градусы или нет. Компьютерный калькулятор использует градусы для вычисления косинуса (обратите внимание, что результат калькулятора равен 0,9999 ..., что очень близко к 1. Косинус нуля равен 1), тогда как функция косинуса, предложенная в в радианах. Попробуйте умножить ваше значение на PI / 180.0 и посмотрите, соответствует ли результат вашим ожиданиям.

2 голосов
/ 21 сентября 2009

Ваш калькулятор использует градусы. Например:

>>> import math
>>> math.cos (.3)
0.95533648912560598
>>> math.cos (.3 * math.pi / 180)  # convert to degrees
0.99998629224742674
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...