Как я могу обойти тот факт, что в C ++, sin (M_PI) не 0? - PullRequest
14 голосов
/ 20 апреля 2010

В С ++,

const double Pi = 3.14159265;
cout << sin(Pi);                          // displays: 3.58979e-009

ДОЛЖЕН отображаться номер ноль

Я понимаю, что это потому, что Pi аппроксимируется, но есть ли какой-нибудь способ, которым я могу жестко закодировать значение Pi в моей программе, которое вернет 0 для sin (Pi)? (может быть другая константа?)

В случае, если вам интересно, что я пытаюсь сделать: я конвертирую полярность в прямоугольник, и хотя есть некоторые приемы printf (), которые я могу сделать, чтобы напечатать его как «0.00», он все еще не последовательно возвращать приличные значения (в некоторых случаях я получаю «-0,00»)

Строки, которые требуют греха и косинуса:

x = r*sin(theta);
y = r*cos(theta);

Кстати: мой прямоугольник -> Polar работает нормально ... это просто полярник -> прямоугольник

Спасибо!

edit: Я ищу обходной путь, чтобы я мог вывести на консоль sin (несколько кратных Pi) в виде удобного круглого числа (в идеале без тысячи операторов if)

Ответы [ 14 ]

0 голосов
/ 20 апреля 2010
double cut(double value, double cutoff=1e-7) {
  return (abs(value) > cutoff)*value;
}

это обнулит значения ниже порогового значения, используйте его следующим образом cut(sin(Pi))

0 голосов
/ 20 апреля 2010

Вы знаете, просто для математической корректности: sin (3.14159265) ins't ноль.Это приблизительно ноль, что именно то, что программа говорит вам.Для расчетов это число должно дать вам хороший результат.Для отображения это отстой, поэтому всякий раз, когда вы печатаете число с плавающей точкой, обязательно форматируйте число.

Я не думаю, что здесь есть какая-либо механика с плавающей точкой ... это просто математика.

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

0 голосов
/ 20 апреля 2010

Если вы используете float или double в математических операциях, вы никогда не получите точных результатов. Причина в том, что в компьютере все хранится как степень 2. Это не совсем соответствует нашей десятичной системе счисления. (Примером является отсутствие представления в базе 2 из 0,1)

Кроме того, float и double являются 64-битными по крайней мере на некоторых компиляторах и платформах. (Я думаю - кто-нибудь поправит меня, если понадобится). Это приведет к некоторым ошибкам округления либо для очень больших значений, либо для очень малых значений (0,0000000000xxx)

Чтобы получить точные результаты, вам понадобится большая целочисленная библиотека.

Как написано в комментариях к вопросу выше смотрите на сайте ... http://docs.sun.com/source/806-3568/ncg_goldberg.html

0 голосов
/ 20 апреля 2010

Более значимые цифры могут помочь. Мой компилятор C (gcc) использует константу 3.14159265358979323846 для M_PI в "math.h". Кроме этого, вариантов не так много. Создание собственной функции для проверки ответа (как описано в другом ответе на ваш вопрос), вероятно, является лучшей идеей.

...