| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > Java: Общие вопросы > Математические расчеты в Java |
| Автор: Гость_Владимир 1.11.2005, 11:57 |
| День добрый! Есть задачка, где нужен cos(Pi/2). Насколько я знаю из школьного курса математики, это равно 0. Однако, получается следующая ерунда: fi = (Math.Pi/2); cos_fi = Math.cos(fi); А в результате Cos угла fi оказывается равен 6.....Е-17. Почему так? Заранее благодарен. С уважением. |
| Автор: LSD 1.11.2005, 12:01 |
| Погрешность вычислений. ИМХО 17-й знак после запятой вполне приемлимая точность. |
| Автор: Гость_Владимир 1.11.2005, 14:21 |
| А если данное значение подставляется в формулу, то можно ли его считать нулем? Заранее спасибо. |
| Автор: LSD 1.11.2005, 14:34 |
| Если умножать некое большое число на 0.00000000000000006, то конечно ноль мы не получим. Но промежуточные результаты можно округлять например. |
| Автор: Гость_Владимир 1.11.2005, 15:33 |
| Благодарствую! |
| Автор: NotGonnaGetUs 1.11.2005, 15:40 | ||
Потому что число PI имеет бесконечное количество знаков после запятой А ты мало того, что берёшь константу ограниченную 16 знаками, так ещё делишь её на два. А как известно: cos(pi/2 + x) = - sin(x) = -x (при х->0) вот ты и получаешь в результате число порядка 10^-16/17 |
| Автор: val 1.11.2005, 15:59 |
| Скорее всего вычисление происходит через нахождение суммы ряда, аппроксимирующего функцию косинуса, естественно, число членов этого ряда конечно и, как следствие, наличие погрешности аппроксимации, которая и отражается в семнадцатом знаке после запятой. |
| Автор: NotGonnaGetUs 1.11.2005, 16:40 | ||
точность членов ряда тоже конечна. как бы то ни было, что заказали, то и получили - величину отклонение fi от истинного значения pi/2 вот пример: [quot] double fi = (Math.PI/2)+0.000001; double cos_fi = Math.cos(fi); System.out.println("cos: " + cos_fi); [/quot] Получаем "cos: -9.999999998563343E-7" - т.е. то самое отклонение. |
| Автор: Guest 4.11.2005, 12:03 | ||||
Хм. Почему же тогда: fi = (Math.Pi/2); sin_fi = Math.sin(fi); В результате синус фи = 1. Т.е. с косинусом такие вещи не прокатывают, а с синусом со свистом? |
| Автор: maxim1000 4.11.2005, 13:55 |
| есть абсолютная погрешность, а есть относительная при сохранении в double сохраняется мантисса и порядок числа так что в случае с 0.00000001 сохраняется 1e-8 (если не обсчитался нулей) а если 1.00000001, то придется сохранить 1.00000001e0 так вот точность самой мантиссы ограничена, 1 запомнить просто, а 1.00000001 - нужно достаточно бит... Добавлено @ 13:56 т.е. в случае синуса тоже получилось 1.00...001 (например), но из-за погрешности это просто обрезалось... |