Rada, 02.01.2004 23:16:19:
Ну давайте не отвлекаться на частности, типа VC, Borland C, Matlab и т.п. Любые вычисления с плавающей точкой в принципе обладают лишь ограниченной точностью. Тут правила простые: чем меньше операций, тем лучше; группируйте операции с числами близкими по абсолютному значению. Это простые и интуитивные правила, которые многие забывают.
Ага, я про тоже. Могу только добавить, что особая аккуратность нужна с операциями сложежния/вычитания, умножение/деление намного более устойчивы. Отсюда вывод, что для очень маленьких и очень больших заводят разные аккумуляторы, которые тоже могут объединять (суммировать) позже. Не стоит забывать, что все числа храняться в нормализованном виде. Для * и / это нормально, а вот для + и - приходится числа денормализовывать (если у них порядок разный). Не стоит также забывать, что из 64 разрядов, 12 отводяться на характеристику (степень), 1 на знак и 52 на мантиссу (базу). Да-да 52. Т.к. числа храняться в нормлизованном виде, то одна единичка предпологается по умолчанию и в сетке не храниться. Таким образом, на представление числа отводиться 53 бита - последние 2или3 как правило не считаются надежными - в них очень быстро накапливаются ошибки. Отсюда вывод - если вы попытаетесь сложить два числа с разнице в порядке превышающим 2
53, то у вас большее число не измениться. 2
53 это примерно 10
16. Если брать 32 битное число, то там 8 бит степень, 1 знак и 23(24) мантисса. Т.е. для точности всего 23(24)бита. Или, если разница между величинами достигает 10
7, то мы уже наблюдаем проблемы.
Вот, нашел, стандарт IEEE 754,
вот тут можно посмотреть немного подробнее.
Вот вы, Centuriones, привели пример , который является хрестоматийным примером того как НЕЛЬЗЯ работать с таким типом данных.
Чем вам не понравилось такое решение (если вам надо получит список чисел с интервалом в 0.00001):
do i=1,100
a=(i-1)*0.00001
end do
Ему здесь не понравилось то, что надо суммировать где-то результаты, простое суммирование дает эти странные ответы.
В вашей версии при длине цикла порадка O(N) ошибка имеет порядок O(N), а в этом примере O(1) (то есть не зависит от длины цикла). Сравните эти два метода на одной и той же машине и вы увидите разницу.
В качестве генерации констант Ваш метод очень не плох, но он не помогает в задаче автора
И в ответ на ваш вопрос - от ошибок в точности вичислений избавиться невозможно - можно их только снизить.
Золотые слова!
И именно с помощью грамотной организации алгоритмов. Этим занимается целый раздел прикладной математики и без этого было бы невозможным решение многих рутинных числовых задач с приемлемой точностью, неважно на каком железе.
И развит он очень не плохо.
А вычисления с произвольной точностью - они не плохи, но
очень медленны. Но иногда без них не обойтись.