Как преобразовать градусы в радианы?

У меня есть следующая функция для преобразования из радианов в градусы:

float DegreesToRadians(float degrees) {
    return degrees * (PI / 180);
}

Когда я сейчас делаю:

sinf(DegreesToRadians(90));

Это возвращает 1, как и ожидалось. Но, когда я делаю:

sinf(DegreesToRadians(180));

Он возвращает -8.74228e-08. Кто-нибудь знает, почему это происходит? (Это происходит и с cosf, но в обратном порядке: 180 -> -1; 90 -> -8.74228e-08)


person Ams1901    schedule 25.07.2021    source источник
comment
Вы не можете точно представить правильное значение PI / 180.   -  person Andy Turner    schedule 25.07.2021
comment
Тип float имеет ограниченную точность. Попробуйте с double, получится что-то около е-16.   -  person Bob__    schedule 25.07.2021
comment
В дополнение к комментарию Энди рассмотрите возможность использования (обычно определяемой) константы M_PI;   -  person enhzflep    schedule 25.07.2021
comment
Помимо конкретных проблем с Pi, есть общая проблема с математикой с плавающей запятой, о которой вы должны знать: сломан?. Существует поддисциплина числовой анализ для решения таких проблем.   -  person Scheff's Cat    schedule 25.07.2021
comment
В частности, что касается sin и cos, вы можете заметить, что график функции имеет низкий наклон (около 0) в одних интервалах и более высокий (около 1 или -1) в других. Обратные вычисления в интервалах, где он близок к 0, обычно не совсем точны. Это можно улучшить с помощью умных замен, и sin и cos являются хорошим примером для этого. (Где наклон sin(x) близок к 0, наклон cos(x) близок к 1 или -1 и наоборот.)   -  person Scheff's Cat    schedule 25.07.2021


Ответы (2)


Что ж, ваша PI является приближением к реальной математической константе. Тогда ваше преобразование градусов в радианы является приближением к реальному преобразованию, потому что математика с плавающей запятой является приближением. И затем стандартная функция sinf аппроксимирует функцию sin в математике. Таким образом, вы должны ожидать, что ваши результаты будут приблизительными. -8.74228e-08 — число близкое к 0. Это приближение.

person Ayxan Haqverdili    schedule 25.07.2021

Как преобразовать градусы в радианы?

Преобразование градусов OP в радианы разумно.

return degrees * (PI / 180);

когда я делаю: sinf(DegreesToRadians(180)); Он возвращает -8.74228e-08.

Это не соответствует ожиданиям ОП, поскольку degrees * (PI / 180) не было сделано точно, учитывая, что PI не является π. PI – это машинное число пи, ближайшее представимое значение числа π. π — иррациональное число. Все конечные значения с плавающей запятой рациональны. Невозможно сделать non_zero_degrees * (PI / 180) точно. Ошибка в частном усиливается в вызове sinf().

sinf(DegreesToRadians(180)) дает не синус(π), а синус(PI). PI близко к π, но не то же самое. double графический пример.


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

Пример

person chux - Reinstate Monica    schedule 25.07.2021