⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lbbigint.pas

📁 tool pour ubuntu 8.10
💻 PAS
📖 第 1 页 / 共 5 页
字号:
    {***************************************************************************
    {* 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 + -