PDA

Показать полную графическую версию : точность плавающей арифметики


Страниц : [1] 2

bilytur
17-06-2004, 04:01
Как использовать возможности сопроцессора на 100% ?
Почему long double 64 bit?
А не 80 как было в "отсталом" DOC'е
Теряется и точность и скорость.

pva
17-06-2004, 11:26
какой компилятор? какие настройки?

если компилировать под x86 Debug, то:
sizeof(long double)=10
sizeof(double)=8
sizeof(float)=4

если под P-III SSE или AMD 3DNOW, то выгодней использовать float
если под P-IV SSE2, то double (64-бит)

hasherfrog
17-06-2004, 11:26
Для совместимости.
Очень хорошая публикация (http://www.codeproject.com/csharp/LongDouble.asp) по этому поводу. Посмотрите также линки, прведённые автором - там ещё больше по спецификациям IEEE. Можете почитать ещё это (http://www2.hursley.ibm.com/decimal/dbintro.html).

bilytur
18-06-2004, 03:48
pva
MSVC 6.0
void main()
{
  printf("s= %d %d", sizeof(double), sizeof(long double));
}  
results:
s= 8 8
(debug & release)

если под P-III SSE или AMD 3DNOW, то выгодней использовать float
если под P-IV SSE2, то double (64-бит)

Не понял что значит выгодней?
Как записать число, ну допустим 2.7 e+1000
Да и не в только порядке дело, значащих цифр меньше тоже.

hasherfrog
Из первой Вашей ссылки:
I recently found myself needing to read Intel 80-bit long doubles from a binary stream whilst integrating with another system
И дальше, как я понимаю, описывается как этот "нехороший формат" превратить в "хороший" double

Вы меня не поняли.
Мне нужны мат функции работающие с long double 80
sin, cos, log, etc...
Может либа какая-есть?
Можно конечно написать в старом компиляторе 16-разрядную длл со всей математикой, но согласитесь, это похоже на чесание левой рукой за правым ухом.

hasherfrog
18-06-2004, 09:12
bilytur
То есть конвертнуть из 80-битного в 64-битное, а потом уже с этим работать - это Вам не подходит?

bilytur
19-06-2004, 03:27
hasherfrog
Нет. Не подходит.
Я просто хотел использовать возможности железа на 100%
А это как раз 80 битный формат сопроцессора.
Повышенная точность, больший диапазон чисел, ну и скорость.
Не нужно постоянно конвертировать double <=> 80bit
(Ну по крайней мере для x86 это так.)

Удивительно что в Win32 это убрали.
В досе, как я уже говорил это было.
В Паскале например этот тип кажется назывался extended
Может в делфе он и сейчас поддерживается?
Надо спросить у делфистов...

Искал в интере, есть какая-то либа, но скачать только за тугрики. :(
Под *nix правда много что есть. Но мне надо под Win 32.
Еще советуют фортран. :(  
Интеловский компилер по идее должен поддерживать.
Только что пришло в голову.
Попробую поискать.

Vlad Drakula
20-06-2004, 21:19
bilytur
дело в том что с появлением ММХ это уже не так, сейчас регистры для работы с плавающей запятой 64 битные, так что быстрее теперь 64бит доубле.

bgg0408
21-06-2004, 01:12
Vlad Drakula
а ты SSE/SSE2 и 3DNow! учитываешь? ;)
появлением ММХ
Как ни странно, это ЦЕЛОчисленные расширения.... :wink:


Исправлено: bgg0408, 1:13 21-06-2004

Vlad Drakula
21-06-2004, 02:03
bgg0408
именно их я и учитываю, между прочим все эти расширения используют теже регистры что и для вычислений с плавающей запятой, т.е. физчески теже.

bgg0408
21-06-2004, 02:47
Vlad Drakula
именно их я и учитываю
Так сразу и начал бы о них и говорить!
MMX все-таки не SSE.
физчески теже.
Согласен. Открываем Гука (или аналогичную книгу) и начинаем читать :)

bilytur
21-06-2004, 03:13
А если прога должна работать на любом компе, начиная с 486
Быстродействие в принципе не так важно.
(Я пишу калькулятор, важнее точность.)
Есть же мат сопроцессор.
Хотелось бы его использовать.
И имхо не так уж он и медленно работает.
Или в MMX компах его уже нет?

hasherfrog
21-06-2004, 10:38
Для информации: Кратко об MMX, SSE, FPU (http://www.chipinfo.ru/literature/chipnews/200010/1.html)

Vlad Drakula
21-06-2004, 18:53
bilytur
если нужно точность то писать нужно не на С.
я бы посоветовал выбрать какойнибеть другой язык.
в принципе доубле обеспечивает точность до 12 знаков после запятой.

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

bilytur
для вычислений сбольшой точностью есть специальные библиотеки "бесконечной точность" или библиотеки символьных вычислений, их задача исенно в том чтобы обеспечить большую точность, но быстродействие у них не велико!

bgg0408
22-06-2004, 01:13
Есть же мат сопроцессор.
Хотелось бы его использовать.
И имхо не так уж он и медленно работает.
Или в MMX компах его уже нет?
Сопроцессор есть в любом современном компе. Он "интегрирован" в сам процессор. До 486, как правильно заметил Vlad Drakula, процы и сопроцессоры выполнялись в виде двух отдельных модулей.

Vlad Drakula
если нужно точность то писать нужно не на С.
А на чем же? Можно написать и на Си, лишь бы терпения хватило ;)

Vlad Drakula
22-06-2004, 02:29
bgg0408
для выполнения вычислений с повышенной точность есть другие языки, напимер фартран.

С изначально не расчитавался как язык для мат вычислений.
т.е. это быстрый язык(если так можно выразиться), но это не его стихия.

если писать беблиотеку символьных вычислений самому с нуля, да еще на чистом С... то тут действительно нужно много терпения!

bilytur
22-06-2004, 03:18
Из статьи от hasherfrog
процессоры Pentium содержат 80-разрядные регистры, которые обслуживают блоки FPU и MMX. При работе FPU регистры ST0-ST7 образуют кольцевой стек, в котором хранятся числа с "плавающей точкой", представленные в формате с расширенной точностью (80 разрядов).
И все-таки жаль что нельзя это использовать. (в С под Win32)
(На других языках или других платформах этого запрета нет.)

Vlad Drakula
Да фартран. мне уже предлагали. Спасибо.
Или С, но тогда под ДОСом.  На выбор. :)

Вобщем проблему свою я решил несколько другим способом. (Нашел линуковскую либу, в исходниках. портанул под вин32, вроде скомпилилась и работает.)

Всем большое спасибо.

hasherfrog
22-06-2004, 09:22
место в центре кристало очень дорого
Дело было немного по-другому, имхо: по шине дано было гонять эти регистры, а она 64-бита. Экономили скорее не место, а скорость (коряво сказал как-то).
Но это детали, главное, что bilytur решениевроде бы нашёл. Только вот я не совсем понял...
bilytur
портанул под вин32
А чем компилил? MVC, BC, GNU C??? Что, при компиляции появился новый тип данных? Или там в исходниках полно ассемблерного кода?

bgg0408
23-06-2004, 00:05
Vlad Drakula
Ты не прав. Ты знаешь почему используют ФОРТРАН дял вычислений? Не потому, что это "супер-пупер" язык. Просто много модулей уже написано на нем :( Вот и юзают :(
Можно сделать так:
у нас есть массив char'ов. Каждый элемент - цифра. Складываем два массива => получаем третий с суммой. так можно построить математическую библиотеку. Правда, расход памяти большой, зато просто.

bilytur
23-06-2004, 01:02
А чем компилил? MVC, BC, GNU C??? Что, при компиляции появился новый тип данных? Или там в исходниках полно ассемблерного кода?
hasherfrog
мультипрецижн арифметик:
http://www.swox.com/gmp/

Точность в принципе любая, написан на чистом С (не ++) и асме
Что обрадовало - не фортран.
Я в принципе не против фортрана, просто сейчас я изучаю С/++
Распыляться не хотелось. Да и считаю С языком на котором можно
написать все что угодно. И даже математику. :) . имхо

Вообщето к FPU это отношения не имеет. Но данный вариант меня устраивает
даже больше.


Добавлено:

А да, компилил mingw

pva
30-06-2004, 13:07
У меня никогда проблем не возникало. Если я компилирую под x86, и ставлю флажок "не эмулировать FPU", то всегда используется сопроцессор с полной точностью (80 бит). Если под P-4 SSE2, то иногда, когда компилятор посчитает нужным, используются регистры XMM с точностью 64 бит.
Я использовал Borland C++ Builder 3, 4, 6, Borland C++ 5.02, Intell C++ Compiler 6.0, Metrowerks CodeWarrior 8.0.

О балансе совместимости и быстродействия.

Любой процессор архитектуры IA-32 (т.е. начиная с i486) имеет сопроцессор, который умеет работать с 80-бит long double. Если речь идёт о совместимом софте под винду, то можно смело использовать сопроцессор на полную точность. Если хочется при этом побыстрее - некоторые процессоры работают быстрее с 32-бит float (поэтому его использует Direct3D). При этом нужно делать сопроцессору специальное (программное) переключение. Понятно, что точность при этом резко упадёт. Если планируется использовать функции трансцендентные сопроцессора (sin, cos, ...), то забудьте о скорости. Они считаются сотни тактов (на максимальной точности).
Любой компилятор под x86 должен отводить под long double 80 бит.

Да, чуть не забыл: изначально 80 бит использовалось только внутри сопроцессора, но потом сделали инструкцию, которая может загружать и выгружать из сопроцессора все 80 бит. Любые вычисления приводят к потере точности (также при вычислении трансц. функций, а при умножении - особенно), поэтому хранение всех 80 бит означает и хранение мусора в последних битах. Может по этому ваш комплятор хранит в памяти только 64 бита.

Большую роль играет align. Intel рекомендует укладывать long double по 16 байт.

Если хочется выйти за машинную точность, пробуйте эмулировать сопроцессор.

Расширения процессора SSE и SSE2 работают с плавающей арифметикой. Ускорение достигается за счёт одновременного вычисления однотипных операций и на разных модулях параллельно. SSE работает с float, SSE2 - с double. Трансцендентные функции не сделаны, поэтому intel предлагает либо считать их на сопроцессоре, либо в рядах на SSE (на сайте есть библиотека с исходниками).




© OSzone.net 2001-2012