Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2005.02.27;
Скачать: CL | DM;

Вниз

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

 
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;
Скачать: CL | DM;

Наверх




Память: 0.5 MB
Время: 0.042 c
14-1107540699
Aldor_
2005-02-04 21:11
2005.02.27
Exception vs ErrorCode


3-1106337728
cherrex
2005-01-21 23:02
2005.02.27
Репликация в InterBase


3-1106903250
Oleon
2005-01-28 12:07
2005.02.27
Как в cxGrid выборочные строки выделить другим цветом?


1-1108393470
Gost
2005-02-14 18:04
2005.02.27
Как добавить индексное поле AZZ ?


14-1107501465
Guest__
2005-02-04 10:17
2005.02.27
Что с RSDN?