type TBigInt=class
     FSign: boolean;
     FData: Array of DWORD;
    ....
end;procedure TBigInt._Mul(var A, B, P: TBigInt);
var
  len,lenA,lenB,i,j: integer;
  carry,Re,Half,sum,sum1,sum2: Int64;
begin
  lenA   := A.Size;
  lenB   := B.Size;
  len    := lenA + lenB;
  P.Size := len;  for i:=0 to len-1 do P.FData[i] := 0;  for i := 0 to lenB-1 do
  begin
    carry := 0;
    //以下做法是防止Int64超界
    //A=2^32-1,B/2<2^31-1
    //A*B/2+A=(2^32-1)*(2^31-1)+(2^32-1)=2^63-2^31-2^32+1+2^32-1=2^63-2^31<2^63-1
    Re    := Int64(B.FData[i]) and 1; //m=t mod 2
    Half  := Int64(B.FData[i]) shr 1; //t=t div 2
    for j := 0 to lenA-1 do
    begin
      sum1  := Int64(P.FData[j+i]) + carry;
      sum2  := Int64(A.FData[j]) * Half;
      if Re=1 then sum1 := sum1 + Int64(A.FData[j]);
      sum   := sum1 and $FFFFFFFF + (sum2 and $FFFFFFFF) shl 1; //sum=sum1+sum2*2
      carry :=(sum1 shr 32) + ((sum2 shr 32) shr 1);
      if sum>$FFFFFFFF then
      begin
        P.FData[j+i] := sum and $FFFFFFFF;
        carry        := carry + (sum shr 32);
      end
      else
        P.FData[j+i] := sum;    end;
    P.FData[i+lenA] := carry;
  end;  P.Shrink;
  P.FSign := A.FSign=B.FSign;
end;怎么就是不对呢?看得头大,希望旁观者清了。

解决方案 »

  1.   

    网上倒是找到一个FGInt.Pas,但是仔细一看代码,够糟糕的。首先它用的是Array of Int64,但是实际只用了31位,加密大文件时太浪费了吧。还有,它的转换也很不理想,所有转换都是先转换称二进制的字符串“0101010”,又是一个多余的内存占用。还有大量的Copy和Delete,Str=Str+...,看着就是不爽啊,我准备自己写一个,转换问题,加法,减法都没问题,但乘法有问题,因为DWORD×DWORD可能大于Int64,所以变通一下,但就是不行,希望各位帮忙看一下
      

  2.   

    楼主网上找找,处理此问题的汇编代码。大数乘除的汇编代码
                                           ;******************
    ;A Kinds Production
    ;******************
    ;============================
    ;About MulK,IMulK,DivK,IDivK
    ;Work On 200410011507 At Home
    ;============================
    data segment
     aopr dw 0fffch
     bopr dw 0ffch
     copr dw ?
     result dw ?,?
     l1bit dw 1
     cmpit dw 11b
     l2bit01 dw 1
     l2bit10 dw 2
     af dw 0
     bf dw 0
    data ends
    ;****************************
    stack segment  stack
     dw 256 dup(?)
    tos label word
    stack ends
    ;****************************
    code segment
     assume cs:code,ds:data
     assume es:data,ss:stackMulK macro opr1,opr2
     
     mov ax,opr1
     mov bx,opr2
     sub  dx,dx
     
     mov cx,16d
    lop1: test ax,l1bit
     jz no
     add dx,bx
     jmp step1
    no: add dx,0
    step1: rcr dx,1
     rcr ax,1
     loop lop1 
     
     endmIMulk macro opr1,opr2
     
     mov ax,opr1
     mov bx,opr2
     sub  dx,dx
     
     test ax,1
     jz step2
     sub dx,bx
    step2: sar dx,1
     rcr ax,1
     
     mov cx,15d
    lop2: push ax
     rcl ax,1
     and ax,cmpit
     cmp ax,l2bit01
     jz yes01
     cmp ax,l2bit10
     jz yes10
     jmp step3
    yes01: add dx,bx 
     jmp step3
    yes10: sub dx,bx
    step3: pop ax
     sar dx,1
     rcr ax,1
     loop lop2  
     
     mov result,ax
     mov result+1,dx
     
     endm参考:http://hopy.blogchina.com/1410660.html没细看,没测试,不知道行不行~~呵呵!
      

  3.   

    乘法问题已解决:
     carry :=(sum1 shr 32) + ((sum2 shr 32) shr 1);
    改为
     carry :=(sum1 shr 32) + ((sum2 shr 32) shl 1);真是脑袋进水了啊!现在除法也是同样的问题,Delphi不如C/C++有unsigned啊。汇编不熟悉啊,哪位高手能帮忙用汇编解决,不胜感谢!
    不过,以上两位倒是给我提供了思路,实在不行用C++编译成Obj连接也是一种办法不是?