Mishka: Все сообщения за 2 Января 2004 года

 
ПнВтСрЧтПтСбВс
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31

Mishka

модератор
★★★
Э-э-э. немного неожиданно, прямо скажем. Неужели не у кого не было курса приближенных вычислений в ВУЗе?

Очень точные вычисления тут лежат. Вообще-то ни MS, ни Борланд ни другие "крупные" ребята никогда особенно не заботились о точности. Заботились те, для кого это важно было (смотри ссылку выше).

По памяти - книга Крылова вроде была не плоха. Есть разные специальные методы для повышения точности.
 

Mishka

модератор
★★★
[quote|GrayCat, 02.01.2004 00:14:47:] 2. Насколько я знаю, у Матлаба все числа по умолчанию хранятся как раз в формате сопроцессора (80-бит), так что лишних преобразований не производится.


[/QUOTE]
Весь сопроцессор реализован в соответствии со стандартом IEEE.
 

Mishka

модератор
★★★
au, 01.01.2004 15:43:47:
Только что посчитал ваш пример в матлабе. Ответ: 0.00100000000000
Процессоры интел непричём. Представление чисел с плавающей точкой не позволяет представить все возможные числа. Простых выхода для вас два: считайте или в максимально длинном формате с плавающей точкой чтобы уменьшить ошибки округления, или в целых числах, хоть это и неудобно. Или к нам, в президиум Т.е. матлабом. Там математика написана грамотно. Можно написать функцию в матлабе и скомпилировать в ехе, или прямо из визуала использовать.
 

В Mathlabe та же проблема появиться если оперировать с числами порядка 1е-13
 

Mishka

модератор
★★★
GrayCat, 02.01.2004 20:50:52:
AidarM, 02.01.2004 13:21:07 :
Матлаб все хранит в 64-х битном формате.  Т.е. даже 80-бит нема. Вот. 
Машинный нуль Матлаба ~ 2.2e-16.
 


Тьфу ты, черт, так и есть, 8 байт... Бли-и-ин, аЦтой...
 

Тут дело такое - внутренне сопроцессор всегда работает с 80 битами. Это называется временный формат. Его специально используют для того, чтобы точность у чисел с 64 битами повысить. 32 битные внутри тоже преобразуются в 80 битные. Если записать изначальный алгоритм на ассемблере, то ошибок не будет.
 

Mishka

модератор
★★★
Rada, 02.01.2004 23:16:19:
Ну давайте не отвлекаться на частности, типа VC, Borland C, Matlab и т.п. Любые вычисления с плавающей точкой в принципе обладают лишь ограниченной точностью. Тут правила простые: чем меньше операций, тем лучше; группируйте операции с числами близкими по абсолютному значению. Это простые и интуитивные правила, которые многие забывают.
 

Ага, я про тоже. Могу только добавить, что особая аккуратность нужна с операциями сложежния/вычитания, умножение/деление намного более устойчивы. Отсюда вывод, что для очень маленьких и очень больших заводят разные аккумуляторы, которые тоже могут объединять (суммировать) позже. Не стоит забывать, что все числа храняться в нормализованном виде. Для * и / это нормально, а вот для + и - приходится числа денормализовывать (если у них порядок разный). Не стоит также забывать, что из 64 разрядов, 12 отводяться на характеристику (степень), 1 на знак и 52 на мантиссу (базу). Да-да 52. Т.к. числа храняться в нормлизованном виде, то одна единичка предпологается по умолчанию и в сетке не храниться. Таким образом, на представление числа отводиться 53 бита - последние 2или3 как правило не считаются надежными - в них очень быстро накапливаются ошибки. Отсюда вывод - если вы попытаетесь сложить два числа с разнице в порядке превышающим 253, то у вас большее число не измениться. 253 это примерно 1016. Если брать 32 битное число, то там 8 бит степень, 1 знак и 23(24) мантисса. Т.е. для точности всего 23(24)бита. Или, если разница между величинами достигает 107, то мы уже наблюдаем проблемы.

Вот, нашел, стандарт IEEE 754, вот тут можно посмотреть немного подробнее.

Вот вы, Centuriones, привели пример , который является хрестоматийным примером того как НЕЛЬЗЯ работать с таким типом данных. Чем вам не понравилось такое решение (если вам надо получит список чисел с интервалом в 0.00001):

do i=1,100
a=(i-1)*0.00001
end do
Ему здесь не понравилось то, что надо суммировать где-то результаты, простое суммирование дает эти странные ответы.
 


В вашей версии при длине цикла порадка O(N) ошибка имеет порядок O(N), а в этом примере O(1) (то есть не зависит от длины цикла). Сравните эти два метода на одной и той же машине и вы увидите разницу.
 


В качестве генерации констант Ваш метод очень не плох, но он не помогает в задаче автора :rolleyes:

И в ответ на ваш вопрос - от ошибок в точности вичислений избавиться невозможно - можно их только снизить.
 


Золотые слова!

И именно с помощью грамотной организации алгоритмов. Этим занимается целый раздел прикладной математики и без этого было бы невозможным решение многих рутинных числовых задач с приемлемой точностью, неважно на каком железе.
 


И развит он очень не плохо.

А вычисления с произвольной точностью - они не плохи, но очень медленны. Но иногда без них не обойтись.
 

Mishka

модератор
★★★
Resurrector, 02.01.2004 15:06:19:
Плавающая арифметика - полнейший отствой. Настоящие программисты её никогда не используют.
 

А он не как программист ее использует, а как ученный. И перевод плавающей в целочисленную не помогает - остаются те же проблемы, если только не делать вычисления с произвольной точностью (но это отдельная песня).
 

Mishka

модератор
★★★
GrayCat, 02.01.2004 04:47:12:
Ну, это не проблема Малтаба etc. - это проблема сопроцессора, и, следовательно, всех программ, на него полагающихся. Если для какой-то задачи требуется бОльшая точность, или если алгоритм предполагает такие "плохие" операции, как в примере, следует пользоваться программной реализацией математики, с юбой нужной точностью.
 

Пардон, тут я не согласен. Если система предназначена для точных расчетов, то это и ее проблемы тоже. По крайне мере, она должна предоставлять выбор более медленных, но более точных способов выполнять арифметику.

В данном же примере закавыка состоит в том, что внутреннее двоичное представление чисел не может точно отразить десятичное их представление. Например, 1e-5 сопр "видит" как 1.0000000000000001000e-005, ну и дальше, соответственно, накапливает ошибку.
 


Так эта проблема стоит для любого процессора с фиксированным представлением чисел.

Если же взять число, хорошо "ложащееся" на двоичное представление, например, 1/(216)==1.525878906250e-005, то никаких ошибок нет вообще. Т.е. суммирование 100 раз даст ровно 1.5258789062500000000e-003.
 


А попробуй повторить операцию на простых (не двойных) плавающих 218 раз и увидишь ошибку. Сумма перестанет возрастать.

Так что, "Наличие компьютера не избавляет от необходимости думать" © мой
 


О, это точно! Пускай комп считает, а программист думает!
 

Mishka

модератор
★★★
[quote|Centuriones, 02.01.2004 18:01:29:] [quote|Mishka от 02.01.2004 02:56:12:]Э-э-э. немного неожиданно, прямо скажем. Неужели не у кого не было курса приближенных вычислений в ВУЗе?[/QUOTE]

Лично у меня не было. Обычно такие курсы идут у тех, кто обучается по специальности "Прикладная математика". В начале 1980-х в МИСиС такого не было. В МВМИ, который я кончал в 1986 уж подавно. Все изучал самостоятельно.


[/QUOTE]
Пардон, не знал. Я по старой привычке считал, что в Российском образовании это обязаловка.


Может быть в трехтомнике "Искусстве программирования" что-нибудь есть? Сам я эту книгу не читал.
 


Не припомню ничего такого особого. Приду домой посмотрю. У Кнута большей частью дискретная математика и анализ алгоритмов. Попробуй поискать Крылова. Мне казалось, что он прост. Есть статьи и монографии у Марчука, но они более суровы. Я бы поискал у физиков-математиков (те, которые применяют математику для рассчетов). Зайди в гугл и дай что-то вроде high precision calculation - я получил массу ссылок на реализацию конкретных алгоритмов с повышенной точностью - с них можно уже чему-то научиться. А вообще-то Maple, Mathematica - дают офигенную точность - но порой за счет скорости.
 

в начало страницы | новое
 
Поиск
Настройки
Твиттер сайта
Статистика
Рейтинг@Mail.ru