您的位置:首页 > 其它

HugeUtil(大数)支持单元

2008-09-10 21:44 106 查看
unit HugeUtil;

interface

const HugeMax = $8000-16;

type Huge = record

len : word;

dat : array[1..HugeMax] of word;

end;

HugePtr = ^Huge;

procedure AddHuge (var Answer, Add : Huge);

procedure MulHuge (var A : Huge; Mul : integer; var Answer : Huge);

procedure DivHuge (var A : Huge; Del : integer; var Answer : Huge;

var Remainder : integer);

procedure SubHuge (var Answer, Sub : Huge);

procedure ZeroHuge (var L : Huge; Size : word);

procedure CopyHuge (var Fra,Til : Huge);

procedure GetHuge (var P : HugePtr; Size : word);

procedure WriteHuge(var L : Huge; Size: word);

implementation

procedure AddHuge; assembler; asm

cld

push ds

lds di,Answer

les si,Add

seges lodsw

mov cx,ax

clc

@l1:

seges lodsw

adc [si-2],ax

loop @l1

jnb @done

@l2:

add word [si],1

inc si

inc si

jc @l2

@done:

mov si,di

lodsw

shl ax,1

add si,ax

lodsw

or ax,ax

je @d2

inc word [di]

@d2:

pop ds

end;

procedure MulHuge; assembler; asm

cld

push ds

lds si,A

mov bx,Mul

les di,Answer

mov cx,[si]

mov dx,si

inc di

inc di

clc

@l1:

mov ax,[di]

pushf

mul bx

popf

adc ax,si

stosw

mov si,dx

loop @l1

adc si,0

mov es:[di],si

lds di,A

mov di,[di]

mov ax,[di+2]

or ax,ax

je @l2

inc di

inc di

@l2:

lds si,Answer

mov [si],di

pop ds

end;

procedure DivHuge; assembler; asm

std

push ds

lds si,A

mov bx,Del

les di,Answer

mov cx,[si]

mov di,cx

add di,cx

xor dx,dx

@l1:

mov ax,[di]

div bx

stosw

loop @l1

lds si,Remainder

mov [si],dx

lds si,A

mov ax,[si]

lds di,Answer

mov [di],ax

mov si,[di]

shl si,1

@d3:

lodsw

or ax,ax

jne @d2

dec word [di]

jne @d3

inc word [di]

@d2:

pop ds

end;

procedure SubHuge; assembler; asm

cld

push ds

lds di,Answer

les si,Sub

seges lodsw

mov cx,ax

clc

@l1:

seges lodsw

sbb [si-2],ax

loop @l1

jnb @done

@l2:

sub word [si],1

inc si

inc si

jc @l2

@done:

mov si,[di]

shl si,1

std

@d3:

lodsw

or ax,ax

jne @d2

dec word [di]

jne @d3

inc word [di]

@d2:

pop ds

end;

procedure WriteHuge;

var L1, L2, I, R, R1, X : integer;

begin

with L do begin

L1 := Len;

L2 := L1 - 1;

I := 1;

write(dat[L1],'.');

X := 0;

for I := 1 to Size div 4 do begin

Dat[L1] := 0;

Len := L2;

MulHuge(L,10000,L);

R := dat[L1];

R1 := R div 100;

R := R mod 100;

write(chr(R1 div 10+48), chr(R1 mod 10+48),

chr(R div 10+48), chr(R mod 10+48));

inc(X);

write(' ');

if X > 14 then begin

writeln; write(' ');

X := 0

end

end

end;

writeln

end; { WriteHuge }

procedure ZeroHuge;

begin

fillchar(L.Dat, Size * 2, #0);

L.Len := Size

end;

procedure CopyHuge;

begin

move(Fra, Til, Fra.Len * 2 + 2)

end;

procedure GetHuge;

var D : ^byte;

Tries,

Bytes : word;

begin

Bytes := 2 * (Size + 1);

Tries:=0;

repeat

getmem(P,Bytes);

{ To make it possible to use maximally large arrays, and to increase

the speed of the computations, all records of type Huge MUST start

at a segment boundary! }

if ofs(P^) = 0 then begin

ZeroHuge(P^,Size);

exit

end;

inc(Tries);

freemem(P,Bytes);

new(D)

until Tries>10; { if not done yet, it's not likely we ever will be }

writeln('Couldn''t get memory for array');

halt(1)

end; { GetHuge }

end.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: