Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2005.02.27;
Скачать: [xml.tar.bz2];

Вниз

Точность/погрешность вычеслений.   Найти похожие ветки 

 
Vaitek ©   (2005-02-09 16:57) [0]

Я краем уха слышал, что в универах на тему погрешности в вычислениях даже отдельно курсы читают. Но мне никто не читал.

Поэтому вопрос:
А какие использются приемы для минимизации вычеслительных погрешностей? Какое типы использовать? Какие действия предпочтительнее, а какие лучше избегать?

Еще у меня часто бывает так, что во время расчетов вместо чистого нуля в переменную попадает число типа 0.00000001693274
А дальше из за него получаются ошибки в расчетах. Или еще бывает вместо 1 -> 0.999999983243. Тоже не приятно, как со всем этим бороться?


 
Lord Zmiy ©   (2005-02-09 17:03) [1]

сделай допустимую погрешность и говори что если число 0,99999999 и т.д. то число равно нулю

предмет называется Стандартизация и сертификация ... много всяких бесполезных формул а все все равно сводится к округлению :)


 
Vaitek ©   (2005-02-09 17:05) [2]

Округление я и сам могу сделать. Правда предел точности где-то 10^-6. Я почему-то думал что должно быть точнее. Тип Double.


 
Vaitek ©   (2005-02-09 17:09) [3]

Да и когда начинать ловить кривые дроби? Чем раньше тем лучше?


 
Александр Иванов ©   (2005-02-09 17:11) [4]

Lord Zmiy ©   (09.02.05 17:03) [1]
если число 0,99999999 и т.д. то число равно нулю

Странно вы округляете


 
Vaitek ©   (2005-02-09 17:13) [5]

Ну он имел в виду единицу.


 
Юрий Зотов ©   (2005-02-09 18:25) [6]

> Vaitek
http://www.delphikingdom.com/asp/viewitem.asp?catalogid=374

Там найдете объяснения всем "чудесам" и рекомендации по борьбе с ними.


 
Jeer ©   (2005-02-09 19:08) [7]

Юрий Зотов ©   (09.02.05 18:25) [6]

К сожалению, это не совсем то.
Это особенности единичных вычислений.
В том же случае, когда алгоритм вычислений составной, необходимо руководствоваться определенными правилами порядка вычислений.
Есть такое понятие в теории погрешностей, как "распространение погрешности".
Здесь нет места и времени для объяснения, но главное - вычитание должно производится как можно ближе к концу локального или глобального процесса вычислений.


 
Юрий Зотов ©   (2005-02-09 19:22) [8]

> Jeer ©   (09.02.05 19:08) [7]

Я в курсе. Лет 25. Только не все эти правила вполне однозначны (многое зависит от алгоритма и значений данных), а самое главное, что здесь действительно "нет места и времени для объяснения". На эту тему целые книги написаны.

Начинать же в любом случае надо с простого понимания того, что это такое - машинная арифметика с плавающей точкой.


 
Vaitek ©   (2005-02-09 19:42) [9]

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

Проблема в том, что расчет действительно составной. Задача сводится к серии систем линейных уравнений. Число уравнений в систем от 9 до 11, так что ручками совсем не катит по брейкпоинтам лазить. Плюс кое где есть кодой такой примерно:
If t <> 0 then e := 1/t;
А теперь все представили, если t = 0.00000001 8-)

А ошибка - накапливается и все..............
Удалось добится предельной точности ~ 0.0001 - 0.001 - дальше никуда.

Код не привожу, чтобы поберешь ваши нервы. Да и не влезет он сюда.


 
Юрий Зотов ©   (2005-02-09 21:08) [10]

> Vaitek ©   (09.02.05 19:42) [9]
> If t <> 0 then...

Самое простое - переход к типу Extended с выставлением соответствуещего режима FPU. Это помогает, но не всегда спасает.

Для примера - вот возможный (но не всегда приемлемый по смыслу задачи) вариант:
 if Abs(t) >= Eps then...
где Eps - заранее вычисленное (один раз, при старте программы) машинное эпсилон. Что это такое - см. в статье.

> Удалось добится предельной точности ~ 0.0001 - 0.001 - дальше
> никуда.

Обычно это достигается уже вылизыванием алгоритма. Простейший пример - для компьютера A+B-C и A-C+B может быть совсем не одно и то же. Что будет, если значения A и C очень близки друг к другу, а значение B на много порядков меньше?


 
Vaitek ©   (2005-02-10 12:08) [11]

Microsоft на мыло!!!!

Вставил в начале вычеслений:
 Set8087CW(Get8087CW or $0100);

Земенил Double на Extended.

Все расчеты с углами перевел в радианы из градусов.

Кое-где изменил формулы расчетов, минимизируя деления и вычитания.

Получил увеличение точности до 10^-6 10^-8.

Но максимальный прирост был от
 Set8087CW(Get8087CW or $0100);

Пример:
Var
 a,b,c :Extended;
Begin
 a := 0.0;
 b := 23.10;
 c := a-b; //c = -23.100000381
End;

Var
 a,b,c :Extended;
Begin
 Set8087CW(Get8087CW or $0100);
 a := 0.0;
 b := 23.10;
 c := a-b; //c = -23.1
End;
На всякий случай напихал этот Set8087CW перед каждым циклом расчетов и ввода исходных данных.

Статья - супер.

Всем спасибо!



Страницы: 1 вся ветка

Форум: "Основная";
Текущий архив: 2005.02.27;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.47 MB
Время: 0.06 c
10-1084008974
ivs
2004-05-08 13:36
2005.02.27
Передача массива данных


1-1107777773
Zilog
2005-02-07 15:02
2005.02.27
Вывод форматированого текста + графика


1-1108131963
Knoxville
2005-02-11 17:26
2005.02.27
Как рисовать на канве рисунки из bmp?


4-1105310089
Gero
2005-01-10 01:34
2005.02.27
Пользователи и группы


14-1104052102
www.Vlad.uk
2004-12-26 12:08
2005.02.27
Глючит EXPLORER.EXE





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский