![]() |
Модераторы: Daevaorn |
![]() ![]() ![]() |
|
Фантом |
|
|||
![]() Вы это прекратите! ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 1516 Регистрация: 23.3.2008 Репутация: нет Всего: 49 |
Так Вы его и получили. Я совершенно серьезно: при имеющейся точности операндов этот ответ равен 1E-20. Ничего подобного. Вы выполняете вычисления с некоторой точностью, поэтому на каждой стадии неизбежно получаете какую-то погрешность, полное устранение которой невозможно. Соответственно, Вы задали себе принципиально нерешаемую задачу (да еще и бессмысленную с практической точки зрения). Так что дело действительно не в типах и библиотеках. Вам надо просто честно получить оценку погрешности вычисляемых результатов, затем - такую же оценку для "нуля" в контрольном критерии, а затем сравнивать получающуюся невязку с нулем с учетом этой оценки. Если разность меньше - все нормально. |
|||
|
||||
Нитонисе |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 917 Регистрация: 5.11.2009 Репутация: нет Всего: 2 |
А как оценить погрешность вычисления? Я-то сейчас просто грубо отсекаю числа меньше 0.001, как равняющиеся нулю. Но иногда такой подход нежелателен, я отсекаю не нули, а просто малые числа. А так бы действительно - сравнивал бы с погрешностью и жилось бы немного лучше ![]() |
|||
|
||||
Alexeis |
|
|||
![]() Амеба ![]() Профиль Группа: Админ Сообщений: 11743 Регистрация: 12.10.2005 Где: Зеленоград Репутация: 12 Всего: 459 |
Не все десятичные дробные представимы в двоичном виде не периодичной дробью + погрешность вычислений. Добавлено через 5 минут и 23 секунды
Числа с плавающей точкой не сравнивают с нулем, если с ними производились математические операции. Правильнее проверить, что модуль разницы чисел меньше заранее заданной погрешности. Если числа получаются разного порядка, то можно вычислять относительную погрешность. разницу делить на само число и проверять, что погрешность заданное число процентов. -------------------- Vit вечная память. Обсуждение действий администрации форума производятся только в этом форуме гениальность идеи состоит в том, что ее невозможно придумать |
|||
|
||||
math64 |
|
|||
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2505 Регистрация: 12.4.2007 Репутация: 8 Всего: 72 |
При умножении, делении - относительные погрешности складываются.
При сложении и вычитании - складываются абсолютные погрешности. Т.о. при сложении двух чисел одного знака относительная погрешность сохраняется. Вычитания чисел одного знака следует избегать, по возможности использовать альтернативные формулы для вычислений. |
|||
|
||||
Нитонисе |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 917 Регистрация: 5.11.2009 Репутация: нет Всего: 2 |
Я так и поступаю. Просто я погрешность задаю жестко 0.001. Наверно это не лучший способ. А можно пример? А то несовсем понятно.
Какова точность вычисления с? |
|||
|
||||
Alexeis |
|
|||
![]() Амеба ![]() Профиль Группа: Админ Сообщений: 11743 Регистрация: 12.10.2005 Где: Зеленоград Репутация: 12 Всего: 459 |
Нитонисе, суммарная абсолютная погрешность вычисляется через сумму частных производных.
Если da = db = eps - машинное эпсилон Тогда dc = (|b + 1| + |a|) * eps -------------------- Vit вечная память. Обсуждение действий администрации форума производятся только в этом форуме гениальность идеи состоит в том, что ее невозможно придумать |
|||
|
||||
Нитонисе |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 917 Регистрация: 5.11.2009 Репутация: нет Всего: 2 |
||||
|
||||
Фантом |
|
|||
![]() Вы это прекратите! ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 1516 Регистрация: 23.3.2008 Репутация: нет Всего: 49 |
Хм... вообще говоря, в двух словах не расскажешь. Есть древняя, но хорошая книга Демидовича и Марона "Основы вычислительной математики", ее легко найти в сети. Скачайте и прочитайте первую главу, это при таких занятиях будет очень полезно. |
|||
|
||||
Alexeis |
|
|||
![]() Амеба ![]() Профиль Группа: Админ Сообщений: 11743 Регистрация: 12.10.2005 Где: Зеленоград Репутация: 12 Всего: 459 |
-------------------- Vit вечная память. Обсуждение действий администрации форума производятся только в этом форуме гениальность идеи состоит в том, что ее невозможно придумать |
|||
|
||||
Нитонисе |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 917 Регистрация: 5.11.2009 Репутация: нет Всего: 2 |
Немного изменю вычисление.
Погрешность вычисления получается dc = (a + b)*eps, где eps = 1E-5. Точный результат сложения с = 3.5802468. Погрешность dc = 0.000035802468. 'Это значит, что фактически я могу получить результат сложения с = c +/- dc, так? Как же ж мне вычислить погрешность, когда у меня таких вчислений тысячи? ![]() Я посмотрел самое начало - как я понял книга предназначена для приближенных ручных вычислений. Думаю приближенный ручной счет и приближенный машинный - не стоит сравнивать. |
|||
|
||||
Alexeis |
|
||||
![]() Амеба ![]() Профиль Группа: Админ Сообщений: 11743 Регистрация: 12.10.2005 Где: Зеленоград Репутация: 12 Всего: 459 |
Неправильно. в данном случае максимальная погрешность будет 2 * eps . Производная функции y = a + b по а = 1, по b тоже равна 1, поэтому (1 + 1) * eps = 2 * eps .
Обычно стараются выбрать числа такой точности, чтобы погрешность вычисления была на порядок ниже чем погрешность физических величин. В этом случае ей можно пренебречь. Если используются быстрорастущие функции типа экспонент или обратных тригонометрических, то на некоторых участках функции погрешность может уходить в бесконечность. Перед тем как забивать выражения в компьютер нужно оценивать порядки величин и величины погрешности, которые могут возникать на каждом участке выражения. Если выражение вызывает большую потерю точности, то можно изменить порядок вычислений путем расстановки скобок или всяких ухищрений типа логарифмирования (превращает большие числа в малые). Приведу пример. У меня вычислялась экстраполяция параметра по времени. Для отсчета использовался виндовый высокоточный счетчик. Экстраполяция была квадратичной, поэтому аргумент возведенный в квадрат давал число, которое не влезало в дабл, соответственно младшие разряды красиво отрезались и после операций сложения у меня погрешность улетала в бесконечность. Ситуацию удалось исправить использовав в качестве аргумента не само значение счетчика, а разность между текущим значением и значением в опорной точке. Сразу же значение аргумента уменьшилось на 3-4 порядка, а возведенное в квадрат число стало меньше на 6-8 порядков. -------------------- Vit вечная память. Обсуждение действий администрации форума производятся только в этом форуме гениальность идеи состоит в том, что ее невозможно придумать |
||||
|
|||||
Нитонисе |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 917 Регистрация: 5.11.2009 Репутация: нет Всего: 2 |
Дело в том, что это сложно. По одному и тому же алгоритму могут быть обсчитаны как очень крупные, так и очень малые числа... |
|||
|
||||
math64 |
|
|||
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2505 Регистрация: 12.4.2007 Репутация: 8 Всего: 72 |
Можете оценивать точность так:
Это сообщение отредактировал(а) math64 - 27.8.2012, 16:02 |
|||
|
||||
Alexeis |
|
|||
![]() Амеба ![]() Профиль Группа: Админ Сообщений: 11743 Регистрация: 12.10.2005 Где: Зеленоград Репутация: 12 Всего: 459 |
Не сомневаюсь. Вероятно, следует использовать использовать различные тесты для проверки таких алгоритмов и делать шаг проверки аргументов экспоненциальным, чтобы охватить проверкой широкий спектр аргументов. Простого способа "сделать все хорошо" я не знаю ![]() -------------------- Vit вечная память. Обсуждение действий администрации форума производятся только в этом форуме гениальность идеи состоит в том, что ее невозможно придумать |
|||
|
||||
Нитонисе |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 917 Регистрация: 5.11.2009 Репутация: нет Всего: 2 |
||||
|
||||
![]() ![]() ![]() |
Правила форума "С++:Общие вопросы" | |
|
Добро пожаловать!
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn |
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |