📄 lbbigint.pas
字号:
{***************************************************************************
{* if the most sigDigit of the dividend is greater than or
{* equal to that of the divisor, increment the number of
{* digits in the dividend;
{**************************************************************************}
if pBiByteArray(lclDVD.IntBuf.pBuf)[pred(lclDVD.dwUsed)] >=
pBiByteArray(lclDSR.IntBuf.pBuf)[pred(lclDSR.dwUsed)] then begin
LbBiAddByte(lclDVD, cAPPEND_ARRAY, $00);
end;
while(lclDVD.dwUsed < lclDSR.dwUsed)do
LbBiAddByte(lclDVD, cAPPEND_ARRAY, $00);
InxQ := lclDVD.dwUsed - lclDSR.dwUsed + 1;
InxX := lclDVD.dwUsed;
LbBiClear(quotient);
LbBiClear(remainder);
sigDigit := pBiByteArray(lclDSR.IntBuf.pBuf)[pred(lclDSR.dwUsed)];
if (sigDigit = 0) then begin
tmpInt := pred(lclDSR.dwUsed);
while sigDigit = 0 do begin
sigDigit := pBiByteArray(lclDSR.IntBuf.pBuf)[tmpInt];
dec(tmpInt);
if tmpInt < 0 then
raise Exception.Create(sBIQuotientErr);
end;
end;
while InxQ >= 1 do begin
if (lclDVD.dwUsed = 1) then
sigDivd := pBiByteArray(lclDVD.IntBuf.pBuf)[0]
else
sigDivd := integer(pBiByteArray(lclDVD.IntBuf.pBuf)[InxX]) {!!03}
shl 8 + pBiByteArray(lclDVD.IntBuf.pBuf)[pred(InxX)];
lclQT := sigDivd div sigDigit;
if (lclQT <> 0) then begin
if (lclQT >= cBYTE_POSSIBLE_VALUES) then
lclQT := pred(cBYTE_POSSIBLE_VALUES);
LbBiClear(tmpDR);
LbBiMove(tmpDR, lclDSR, InxQ, lclDSR.dwUsed);
LbBiMulByDigitInPlace(tmpDR, lclQT);
while(LbBiCompare(lclDVD, tmpDR) = cLESS_THAN)do begin
dec(lclQT);
if (lclQT = 0) then break;
LbBiClear(tmpDR);
LbBiMove(tmpDR, lclDSR, InxQ, lclDSR.dwUsed);
LbBiMulByDigitInPlace(tmpDR, lclQT);
end;
end;
if (lclQT <> 0) then begin
LbBiAddByte(quotient, InxQ , lclQT);
LbBiSubInPlace (lclDVD, tmpDR);
end;
dec(InxX);
dec(InxQ);
end;
LbBiCopy(remainder, lclDVD, lclDVD.dwUsed);
if (factor <> 0) then begin
if (remainder.dwUsed > 1) then begin
LbBiDivByDigitInPlace(remainder, factor, tmpByte);
end else if (remainder.dwUsed = 1) then begin
tmpByte := pBiByteArray(remainder.IntBuf.pBuf)[0];
tmpByte := tmpByte div factor;
LbBiAddByte(remainder, cPREPEND_ARRAY, tmpByte);
end;
end;
finally
LbBiFree(lclDVD);
LbBiFree(lclDSR);
LbBiFree(tmpDR);
LbBiFree(tmpBN);
if (quotient.dwUsed = 0) then
LbBiAddByte(quotient, cPREPEND_ARRAY, $00);
if (remainder.dwUsed = 0) then begin
LbBiAddByte(remainder, cPREPEND_ARRAY, $00);
end;
LbBiTrimSigZeros(quotient);
LbBiTrimSigZeros(remainder);
end;
end;
{ ------------------------------------------------------------------- }
procedure LbBiDiv(N1 : LbInteger; N2 : LbInteger;
var quotient : LbInteger;
var remainder : LbInteger);
begin
LbBiDivBase(N1, N2, quotient, remainder);
if (N1.bSign = N2.bSign) then
quotient.bSign := cPOSITIVE
else
quotient.bSign := cNEGATIVE;
end;
{ ------------------------------------------------------------------- }
procedure LbBiDivInPlace(var N1 : LbInteger;
N2 : LbInteger;
var remainder : LbInteger);
var
quotient : LbInteger;
begin
LbBiInit(quotient, N1.dwUsed);
try
LbBiDiv(N1, N2, quotient, remainder);
LbBiClear(N1);
N1.dwUsed := quotient.dwUsed;
N1.bSign := quotient.bSign;
if (N1.IntBuf.dwLen < quotient.IntBuf.dwLen) then
LbBiRealloc(N1, quotient.IntBuf.dwLen);
LbBiCopy(N1, quotient, quotient.dwUsed);
finally
LbBiFree(quotient);
end;
end;
{ ------------------------------------------------------------------- }
procedure LbBiMod(N1 : LbInteger; N2 : LbInteger; var remainder : LbInteger);
var
quotient : LbInteger;
begin
LbBiInit(quotient, N2.dwUsed);
LbBiDiv(N1, N2, quotient, remainder);
LbBiFree(quotient);
end;
{ ------------------------------------------------------------------- }
procedure LbBiModInPlace(var N1 : LbInteger; Modulas : LbInteger);
var
remainder : LbInteger;
begin
LbBiInit(remainder, Modulas.dwUsed);
LbBiMod(N1, Modulas, remainder);
LbBiClear(N1);
N1.dwUsed := remainder.dwUsed;
N1.bSign := remainder.bSign;
if (N1.IntBuf.dwLen < remainder.IntBuf.dwLen) then
LbBiRealloc(N1, remainder.IntBuf.dwLen);
LbBiCopy(N1, remainder, remainder.dwUsed);
LbBiFree(remainder);
end;
{ ------------------------------------------------------------------- }
procedure LbBiPowerAndMod(I1 : LbInteger;
exponent : LbInteger;
modulus : LbInteger;
var _Result : LbInteger);
var
BitCount : Integer;
i : Integer;
tmp_byte : byte;
hold : LbInteger;
begin
LbBiClear(_Result);
if (LbBiIsZero(exponent)) then begin
LbBiAddByte(_Result , cPREPEND_ARRAY, $01);
exit;
end;
LbBiInit (hold, cDEFAULT_PRECISION);
try
i := exponent.dwUsed;
LbBiAddByte(_Result , cPREPEND_ARRAY, $01);
while i > 0 do begin
tmp_byte := LbBiGetByteValue(exponent, i);
dec(i);
Bitcount := 8;
tmp_byte := LbBiReverseBits(tmp_byte);
while bitcount > 0 do begin
{r = r^2 mod m }
LbBiMultInPlace(_Result, _Result);
LbBiModInPlace(_Result, modulus);
if Odd(tmp_byte) then begin
{ r = (r * n) mod m }
LbBiMultInPlace(_Result, I1);
LbBiModInPlace(_Result, modulus);
end;
tmp_byte := tmp_byte shr 1;
dec(Bitcount);
end;
end;
finally
LbBiFree(hold);
end;
end;
{ ------------------------------------------------------------------- }
procedure LbBiPowerAndModInPLace(var I1 : LbInteger;
exponent : LbInteger;
modulus : LbInteger);
var
_Result : LbInteger;
begin
LbBiInit(_Result, cUSE_DEFAULT_PRECISION);
try
LbBiPowerAndMod(I1, exponent, modulus, _Result);
LbBiClear(I1);
I1.dwUsed := _Result.dwUsed;
I1.bSign := _Result.bSign;
if (I1.IntBuf.dwLen < _Result.IntBuf.dwLen) then
LbBiRealloc(I1, _Result.IntBuf.dwLen);
LbBiCopy(I1, _Result, _Result.dwUsed);
finally
LbBiFree(_Result);
end;
end;
{ ------------------------------------------------------------------- }
procedure LbBiAddByDigit(N1 : LbInteger; N2 : byte; var Sum : LbInteger);
var
tmp : LbInteger;
begin
LbBiInit(tmp, N1.dwUsed);
try
LbBiAddByte(tmp, cPREPEND_ARRAY, N2);
LbBiAdd(N1, tmp, sum);
finally
LbBiFree(tmp);
end;
end;
{ ------------------------------------------------------------------- }
procedure LbBiSubByDigit(N1 : LbInteger; N2 : byte; var Sum : LbInteger);
var
tmp : LbInteger;
begin
LbBiInit(tmp, N1.dwUsed);
try
LbBiAddByte(tmp, cPREPEND_ARRAY, N2);
LbBiSub(N1, tmp, sum);
finally
LbBiFree(tmp);
end;
end;
{ ------------------------------------------------------------------- }
procedure LbBiAddByDigitInPlace(var N1 : LbInteger; N2 : byte);
var
sum : LbInteger;
begin
LbBiInit(sum, N1.dwUsed);
try
LbBiAddByDigit(N1, N2, sum);
LbBiClear(N1);
N1.dwUsed := sum.dwUsed;
N1.bSign := sum.bSign;
if (N1.IntBuf.dwLen < sum.IntBuf.dwLen) then
LbBiRealloc(N1, sum.IntBuf.dwLen);
LbBiCopy(N1 , sum, sum.dwUsed);
finally
LbBiFree(sum);
end;
end;
{ ------------------------------------------------------------------- }
procedure LbBiSubByDigitInPlace(var N1 : LbInteger; N2 : byte);
var
diff : LbInteger;
begin
LbBiInit(diff, N1.dwUsed);
try
LbBiSubByDigit(N1, N2, diff);
LbBiClear(N1);
N1.dwUsed := diff.dwUsed;
N1.bSign := diff.bSign;
if (N1.IntBuf.dwLen < diff.IntBuf.dwLen) then
LbBiRealloc(N1, diff.IntBuf.dwLen);
LbBiCopy(N1 , diff, diff.dwUsed);
finally
LbBiFree(diff);
end;
end;
{ ------------------------------------------------------------------- }
procedure LbBiReverseBytes(N1 : LbInteger; var N2 : LbInteger);
var
tmp_ptr : pByte;
cnt : integer; {!!03}
begin
tmp_ptr := N2.IntBuf.pBuf;
FillChar(N2, SizeOf(N2), $00);
N2.IntBuf.pBuf := tmp_ptr;
N2.bSign := N1.bSign;
N2.dwUsed := 0;
if (N2.IntBuf.dwLen < N1.IntBuf.dwLen) then
LbBiRealloc(N2, N1.IntBuf.dwLen);
for cnt := N1.dwUsed downto 1 do begin
LbBiAddByte(N2 , cAPPEND_ARRAY, LbBiGetByteValue(N1, cnt));
end;
end;
{ ------------------------------------------------------------------- }
procedure LbBiReverseBytesInPlace(var N1 : LbInteger);
var
rev : LbInteger;
begin
LbBiInit(rev, N1.IntBuf.dwLen);
try
LbBiReverseBytes (N1, rev);
LbBiClear(N1);
N1.dwUsed := rev.dwUsed;
N1.bSign := rev.bSign;
LbBiCopy(N1, rev, rev.dwUsed);
finally
LbBiFree(rev);
end;
end;
{ ------------------------------------------------------------------- }
procedure LbBiReverseAllBits(N1 : LbInteger; var N2 : LbInteger);
var
i : integer; {!!03}
byt_ptr : pByte;
begin
LbBiReverseBytes(N1, N2);
byt_ptr := N2.IntBuf.pBuf;
for i := 1 to N2.dwUsed do begin
byt_ptr^ := LbBiReverseBits(byt_ptr^);
Inc(Longint(byt_ptr));
end;
end;
{ ------------------------------------------------------------------- }
procedure LbBiReverseBitsInPlace(var N1 : LbInteger);
var
rev : LbInteger;
begin
LbBiInit(rev, N1.IntBuf.dwLen);
try
LbBiReverseAllBits(N1, rev);
LbBiClear(N1);
N1.dwUsed := rev.dwUsed;
N1.bSign := rev.bSign;
LbBiCopy(N1, rev, rev.dwUsed);
finally
LbBiFree(rev);
end;
end;
{ ------------------------------------------------------------------- }
procedure LbBiAddBuf(var N1 : LbInteger; place : integer; buf : pByte; {!!03}
length : Integer);
var
totalLen : integer; {!!03}
ptr : pByte;
begin
if (place = cAPPEND_ARRAY) then begin
totalLen := succ(N1.dwUsed + integer(length)); {!!03}
if (totalLen > N1.IntBuf.dwLen) then
LbBiRealloc(N1, totalLen);
ptr := N1.IntBuf.pBuf;
inc(ptr, N1.dwUsed);
move(buf^, ptr^, length);
inc(N1.dwUsed, length);
end else begin
totalLen := pred(place) + integer(length); {!!03}
if (totalLen > N1.IntBuf.dwLen) then
LbBiRealloc(N1, totalLen);
ptr := N1.IntBuf.pBuf;
inc(ptr, pred(place));
move(buf^, ptr^, length);
if (N1.dwUsed < totalLen) then
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -