1. Библиотеки, для работы с большими числами:
bigshit
biglib
Математические библиотеки
-
- Attachments
-
-
biglib.zip (20.94 KiB)
- BigLib
Downloaded 359 times
-
bigshit09.zip (11.06 KiB)
- bigshit
Downloaded 352 times
-
Примеры конечно интересные, но больно уж накручено. Вот бы что-то попроще и помельче. Начать что ли свою библиотеку подобную Box_Lib и Proc_Lib. Единственный минус, что мне сейчас реально нужна бывает только процедура деления. Остальное и выделять то в библиотеку смешно как-то. В самом деле не будешь же выделять простейшее imul eax,ebx, а вот с делением приходится повозиться и тащить в каждую программу кусок вроде нижеприведенного:
Иногда просто хочется иметь простенькие и достаточно эффективные процедуры математики без задействования FPU. Тем более что в некоторых случаях он оказывается слабоватым, к примеру в eBox из-за этого проигрывание видео тормозится, да время расчета с использованием FPU не всегда гарантировано. В общем как воздух нужна библиотека лишенная этих недостатков.
Spoiler:
Code: Select all
integer_division:
; eax = eax/ebx
test ebx,ebx
jnz @f
inc ebx
@@:
xor edx,edx
div ebx
shl edx,1
cmp ebx,edx
jb @f
inc eax
;@@:
ret
Mario, я думаю, что при вызове библиотеки ради одного-двух таких кусочков, накладные расходы больно большими получаются. Ну а ежели таких кусков много используется (в том числе и более сложных), тогда уже да... В свою очередь предлагаю написанный мной алгоритм извлечения квадратного корня добавить в такую библиотеку, ежели кто займëтся оной:
функция довольно неплохая, на мой взгляд, я потратил на неë довольно много времени
Spoiler:
Code: Select all
sqrt: ;24 code (not comments) strings
;in: eax-number; out: ebx-result of fullnumber sqrt,
; if eax wasn't changed, ebx is ideal result, else:
; ecx-(bigger-ideal), eax-(ideal-smaller);
; result is bigger than floatpoint if ecx<eax, else smaller;
; to find percentage, b=ecx/(ecx+eax), s=eax/(ecx+eax):
; ((b>>0)=>b is nearly to ideal, for s is same; always<1)
cmp eax,0
jne @f
xor ebx,ebx
ret
@@:
mov ebx,-1
xor ecx,ecx
@@:
add ebx,2
add ecx,ebx
cmp ecx,eax
je @f ; we don't need to find nearly result, ecx is this.
jb @b
;now: ecx-bigger square, (ecx-ebx)-smaller, eax-ideal;
;need: check, what square mostly near to input number.
sub ecx,eax
mov eax,ebx
sub eax,ecx ; eax=ebx-(ecx-eax)=eax-(ecx-ebx)=ideal-smaller.
cmp ecx,eax ; cmp(bigger-ideal,ideal-smaller).
jb @f ; ecx mostly near.
sub ebx,2 ; it will be incremented soon, so lets annihilate this.
;crushed: eax; now: ecx,eax-see header.
@@: ; ecx is better
inc ebx
shr ebx,1
ret
И мы уже давно не пешки,
Мы пули, мы орлы, и решки!
Война ютит бинарный код,
Умри, или иди вперед!
Мы пули, мы орлы, и решки!
Война ютит бинарный код,
Умри, или иди вперед!
Ну, так собственно потому я и расплывался мысльюGluk wrote:Mario, я думаю, что при вызове библиотеки ради одного-двух таких кусочков, накладные расходы больно большими получаются. Ну а ежели таких кусков много используется (в том числе и более сложных), тогда уже да...
Вот за это спасибо! Еще бы реализовать синус.Gluk wrote:В свою очередь предлагаю написанный мной алгоритм извлечения квадратного корня добавить в такую библиотеку, ежели кто займëтся оной:
А табличный метод не подходит?
Табличный метод ограничен размерами памяти.
Нужно в float или пойдет int в виде sin (x) * 100, к примеру? Какая точность нужна? Каких углов?
sin*255 мне видится логичнее, для одного байта
И мы уже давно не пешки,
Мы пули, мы орлы, и решки!
Война ютит бинарный код,
Умри, или иди вперед!
Мы пули, мы орлы, и решки!
Война ютит бинарный код,
Умри, или иди вперед!
И как мы потом будем скрещивать ужа с ежом? ЯВУ код с асм кодом подружить в одной *.obj библиотеке проблематично.
Насчет точности не знаю пока.
Насчет точности не знаю пока.
Можно и на ассемблере ведь. Быстро и экономично, мне кажется, так:
1) Создание таблицы для 90*n значений (точность зависит от n), расчет через примитивное разложение x-(x^3)/6+(x^5)/120...
Займет, допустим, 360*n байт памяти - не так уж и накладно
2) Затем линейное интерполирование (прям из книжки пример)
x1 = x*(количество_значений_в_массиве)/pi
y1 = (элемент_массива_номер_x1)
y2 = (элемент массива_номер_x1+1)
Синус = y1 + (y2-y1)*(x*(количество значений в массиве)/pi-x1)
Точность будет, скорее всего, достаточная. И зависеть будет от первого пункта - насколько точно разложили в ряд и сколько элементов в таблицу положили. И скорость будет хорошая.
1) Создание таблицы для 90*n значений (точность зависит от n), расчет через примитивное разложение x-(x^3)/6+(x^5)/120...
Займет, допустим, 360*n байт памяти - не так уж и накладно
2) Затем линейное интерполирование (прям из книжки пример)
x1 = x*(количество_значений_в_массиве)/pi
y1 = (элемент_массива_номер_x1)
y2 = (элемент массива_номер_x1+1)
Синус = y1 + (y2-y1)*(x*(количество значений в массиве)/pi-x1)
Точность будет, скорее всего, достаточная. И зависеть будет от первого пункта - насколько точно разложили в ряд и сколько элементов в таблицу положили. И скорость будет хорошая.
а FPU не катит ?
Я уже имел счастье наблюдать, что на eBox таки хреново катит FPU.
Извините, что встреваю, могу рассказать баян. В FastMM для Delphi видел классную функцию CardinalToStrBuf, обходящуюся без деления вообще:
Тип Cardinal в Delphi -- это DWORD.
Spoiler:
Code: Select all
{Converts a cardinal to string at the buffer location, returning the new
buffer position. Note: Only supports numbers up to 2^31.}
function CardinalToStrBuf(ACardinal: Cardinal; APBuffer: PAnsiChar): PAnsiChar;
asm
{On entry: eax = ACardinal, edx = ABuffer}
push edi
mov edi, edx //Pointer to the first character in edi
{Calculate leading digit: divide the number by 1e9}
add eax, 1 //Increment the number
mov edx, $89705F41 //1e9 reciprocal
mul edx //Multplying with reciprocal
shr eax, 30 //Save fraction bits
mov ecx, edx //First digit in bits <31:29>
and edx, $1FFFFFFF //Filter fraction part edx<28:0>
shr ecx, 29 //Get leading digit into accumulator
lea edx, [edx + 4 * edx] //Calculate ...
add edx, eax //... 5*fraction
mov eax, ecx //Copy leading digit
or eax, '0' //Convert digit to ASCII
mov [edi], al //Store digit out to memory
{Calculate digit #2}
mov eax, edx //Point format such that 1.0 = 2^28
cmp ecx, 1 //Any non-zero digit yet ?
sbb edi, -1 //Yes->increment ptr, No->keep old ptr
shr eax, 28 //Next digit
and edx, $0fffffff //Fraction part edx<27:0>
or ecx, eax //Accumulate next digit
or eax, '0' //Convert digit to ASCII
mov [edi], al //Store digit out to memory
{Calculate digit #3}
lea eax, [edx * 4 + edx] //5*fraction, new digit eax<31:27>
lea edx, [edx * 4 + edx] //5*fraction, new fraction edx<26:0>
cmp ecx, 1 //Any non-zero digit yet ?
sbb edi, -1 //Yes->increment ptr, No->keep old ptr
shr eax, 27 //Next digit
and edx, $07ffffff //Fraction part
or ecx, eax //Accumulate next digit
or eax, '0' //Convert digit to ASCII
mov [edi], al //Store digit out to memory
{Calculate digit #4}
lea eax, [edx * 4 + edx] //5*fraction, new digit eax<31:26>
lea edx, [edx * 4 + edx] //5*fraction, new fraction edx<25:0>
cmp ecx, 1 //Any non-zero digit yet ?
sbb edi, -1 //Yes->increment ptr, No->keep old ptr
shr eax, 26 //Next digit
and edx, $03ffffff //Fraction part
or ecx, eax //Accumulate next digit
or eax, '0' //Convert digit to ASCII
mov [edi], al //Store digit out to memory
{Calculate digit #5}
lea eax, [edx * 4 + edx] //5*fraction, new digit eax<31:25>
lea edx, [edx * 4 + edx] //5*fraction, new fraction edx<24:0>
cmp ecx, 1 //Any non-zero digit yet ?
sbb edi, -1 //Yes->increment ptr, No->keep old ptr
shr eax, 25 //Next digit
and edx, $01ffffff //Fraction part
or ecx, eax //Accumulate next digit
or eax, '0' //Convert digit to ASCII
mov [edi], al //Store digit out to memory
{Calculate digit #6}
lea eax, [edx * 4 + edx] //5*fraction, new digit eax<31:24>
lea edx, [edx * 4 + edx] //5*fraction, new fraction edx<23:0>
cmp ecx, 1 //Any non-zero digit yet ?
sbb edi, -1 //Yes->increment ptr, No->keep old ptr
shr eax, 24 //Next digit
and edx, $00ffffff //Fraction part
or ecx, eax //Accumulate next digit
or eax, '0' //Convert digit to ASCII
mov [edi], al //Store digit out to memory
{Calculate digit #7}
lea eax, [edx * 4 + edx] //5*fraction, new digit eax<31:23>
lea edx, [edx * 4 + edx] //5*fraction, new fraction edx<31:23>
cmp ecx, 1 //Any non-zero digit yet ?
sbb edi, -1 //Yes->increment ptr, No->keep old ptr
shr eax, 23 //Next digit
and edx, $007fffff //Fraction part
or ecx, eax //Accumulate next digit
or eax, '0' //Convert digit to ASCII
mov [edi], al //Store digit out to memory
{Calculate digit #8}
lea eax, [edx * 4 + edx] //5*fraction, new digit eax<31:22>
lea edx, [edx * 4 + edx] //5*fraction, new fraction edx<22:0>
cmp ecx, 1 //Any non-zero digit yet ?
sbb edi, -1 //Yes->increment ptr, No->keep old ptr
shr eax, 22 //Next digit
and edx, $003fffff //Fraction part
or ecx, eax //Accumulate next digit
or eax, '0' //Convert digit to ASCII
mov [edi], al //Store digit out to memory
{Calculate digit #9}
lea eax, [edx * 4 + edx] //5*fraction, new digit eax<31:21>
lea edx, [edx * 4 + edx] //5*fraction, new fraction edx<21:0>
cmp ecx, 1 //Any non-zero digit yet ?
sbb edi, -1 //Yes->increment ptr, No->keep old ptr
shr eax, 21 //Next digit
and edx, $001fffff //Fraction part
or ecx, eax //Accumulate next digit
or eax, '0' //Convert digit to ASCII
mov [edi], al //Store digit out to memory
{Calculate digit #10}
lea eax, [edx * 4 + edx] //5*fraction, new digit eax<31:20>
cmp ecx, 1 //Any-non-zero digit yet ?
sbb edi, -1 //Yes->increment ptr, No->keep old ptr
shr eax, 20 //Next digit
or eax, '0' //Convert digit to ASCII
mov [edi], al //Store last digit and end marker out to memory
{Return a pointer to the next character}
lea eax, [edi + 1]
{Restore edi}
pop edi
end;
Mario
Там и целочисленные тормозить будут, если сравнивать с K8+ и P6+.
Надо смотреть точность алгоритмов, а то эта математика насчитает...
Там и целочисленные тормозить будут, если сравнивать с K8+ и P6+.
Надо смотреть точность алгоритмов, а то эта математика насчитает...
Товарищи, среди нас тайный агент ЯВУшников! Только он мог предложить такой алгоритм, чтобы ЯВУшники смогли показать на http://hackersdelight.org/HDcode/isqrt.c.txt и применить один из своих любимых доводов "ассемблерщики слишком заняты мелкими проблемами вместо того, чтобы использовать более сложные, но более быстрые алгоритмы".
Who is online
Users browsing this forum: No registered users and 36 guests