Математические библиотеки
Posted: Sun Apr 10, 2011 10:39 am
1. Библиотеки, для работы с большими числами:
bigshit
biglib
bigshit
biglib
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
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:В свою очередь предлагаю написанный мной алгоритм извлечения квадратного корня добавить в такую библиотеку, ежели кто займëтся оной:
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;