N天前zswang (伴水)兄贴了段实现无限位加法,乘法的代码!可惜少了两种!减法上次已补充了,这次贴个完整版!加减乘除都全了!uses StrUtils, Math;function StrLeft(const mStr: string; mDelimiter: string): string;
begin
  Result := Copy(mStr, 1, Pos(mDelimiter, mStr) - 1);
end; { StrLeft }function StrRight(const mStr: string; mDelimiter: string): string;
begin
  if Pos(mDelimiter, mStr) <= 0 then
    Result := ''
  else Result := Copy(mStr, Pos(mDelimiter, mStr) + Length(mDelimiter), MaxInt);
end; { StrRight }function formatnum(mNumber: string):string;
var
m:integer;
TemStr:string;
begin
  Result:='';
  for m:=1 to Length(mNumber) do
  begin
    if mNumber[m]='.' then
      Result:=Result+'.'
    else
      Result:=Result+IntToStr(StrToIntDef(mNumber[m], 0));
  end;
  while Pos('0', Result) = 1 do Delete(Result, 1, 1); //排除整数前无效的0
  if Pos('.', Result )<= 0 then Result := Result + '.'; //没有有小数点补小数点
  TemStr:=StrRight(Result,'.');
  while Copy(TemStr, Length(TemStr), 1) = '0' do Delete(TemStr, Length(TemStr), 1); //排除小数后无效的0
  Result:=StrLeft(Result,'.')+'.'+TemStr;
  if Copy(Result, Length(Result), 1) = '.' then Delete(Result, Length(Result), 1); //排除无效小数点
  if Result[1]='.' then Result:='0'+Result;
  if (Result = '') then Result := '0';
end;function InfiniteAdd(mNumberA, mNumberB: string): string; { 无限位数加法 }
var
  I: Integer;
  T: Integer;
begin
  Result := '';
  if Pos('.', mNumberA) <= 0 then mNumberA := mNumberA + '.'; //没有有小数点补小数点
  if Pos('.', mNumberB) <= 0 then mNumberB := mNumberB + '.'; //没有有小数点补小数点
  I := Max(Length(StrLeft(mNumberA, '.')), Length(StrLeft(mNumberB, '.'))); //整数部分最大长度
  mNumberA := DupeString('0', I - Length(StrLeft(mNumberA, '.'))) + mNumberA; //整数前补0
  mNumberB := DupeString('0', I - Length(StrLeft(mNumberB, '.'))) + mNumberB; //整数前补0
  T := Max(Length(StrRight(mNumberA, '.')), Length(StrRight(mNumberB, '.'))); //小数部分最大长度
  mNumberA := mNumberA + DupeString('0', T - Length(StrRight(mNumberA, '.'))); //小数后补0
  mNumberB := mNumberB + DupeString('0', T - Length(StrRight(mNumberB, '.'))); //小数后补0
  I := I + T + 1; //计算总长度//小数长度和整数长度加上小数点长度
  T := 0; //进位数初始化
  for I := I downto 1 do //从后向前扫描
    if [mNumberA[I], mNumberB[I]] <> ['.'] then begin //不是小数点时
      T := StrToIntDef(mNumberA[I], 0) + T; //累加当前数位
      T := StrToIntDef(mNumberB[I], 0) + T; //累加当前数位
      Result := IntToStr(T mod 10) + Result; //计算当前数位上的数字
      T := T div 10; //计算进位数
    end else Result := '.' + Result; //加上小数点
  if T <> 0 then Result := IntToStr(T mod 10) + Result; //处理进位数
  while Pos('0', Result) = 1 do Delete(Result, 1, 1); //排除整数前无效的0
  while Copy(Result, Length(Result), 1) = '0' do
    Delete(Result, Length(Result), 1); //排除小数后无效的0
  if Copy(Result, Length(Result), 1) = '.' then
    Delete(Result, Length(Result), 1); //排除无效小数点
  if Copy(Result, 1, 1) = '.' then Result := '0' + Result; //处理无0小数情况
  if (Result = '') then Result := '0'; //处理空字符情况
end; { InfiniteAdd }function InfiniteMult(mNumberA, mNumberB: string): string; { 无限位数乘法 }  function fMult(mNumber: string; mByte: Byte): string; { 无限位数乘法子函数 }
  var
    I: Integer;
    T: Integer;
  begin
    Result := '';
    T := 0;
    for I := Length(mNumber) downto 1 do begin //从后向前扫描
      T := StrToIntDef(mNumber[I], 0) * mByte + T; //累加当前数位
      Result := IntToStr(T mod 10) + Result; //计算当前数位上的数字
      T := T div 10; //计算进位数
    end;
    if T <> 0 then Result := IntToStr(T mod 10) + Result; //处理进位数
  end; { fMult }var
  I: Integer;
  vDecimal: Integer; //小数位数
  T: string;
begin
  Result := '';
  ///////Begin 处理小数
  if Pos('.', mNumberA) <= 0 then mNumberA := mNumberA + '.'; //没有有小数点补小数点
  if Pos('.', mNumberB) <= 0 then mNumberB := mNumberB + '.'; //没有有小数点补小数点
  vDecimal := Length(StrRight(mNumberA, '.')) + Length(StrRight(mNumberB, '.')); //计算小数位数
  mNumberA := StrLeft(mNumberA, '.') + StrRight(mNumberA, '.'); //删除小数点
  mNumberB := StrLeft(mNumberB, '.') + StrRight(mNumberB, '.'); //删除小数点
  ///////End 处理小数
  T := '';
  for I := Length(mNumberB) downto 1 do begin
    Result := InfiniteAdd(Result, fMult(mNumberA, StrToIntDef(mNumberB[I], 0)) + T);
    T := T + '0';
  end;
  Insert('.', Result, Length(Result) - vDecimal + 1);
  while Pos('0', Result) = 1 do Delete(Result, 1, 1); //排除整数前无效的0
  while Copy(Result, Length(Result), 1) = '0' do
    Delete(Result, Length(Result), 1); //排除小数后无效的0
  if Copy(Result, Length(Result), 1) = '.' then
    Delete(Result, Length(Result), 1); //排除无效小数点
  if Copy(Result, 1, 1) = '.' then Result := '0' + Result; //处理无0小数情况
  if (Result = '') then Result := '0'; //处理空字符情况
end; { InfiniteMult }function InfiniteSub(mNumberA, mNumberB: string): string; { 无限位数减法 }
var
  I: Integer;
  T: Integer;
  TemNumA:String;
  minus:Boolean;
begin
  Result := '';
  mNumberA:=formatnum(mNumberA);
  mNumberB:=formatnum(mNumberB);
  if Pos('.', mNumberA) <= 0 then mNumberA := mNumberA + '.'; //没有有小数点补小数点
  if Pos('.', mNumberB) <= 0 then mNumberB := mNumberB + '.'; //没有有小数点补小数点
  I := Max(Length(StrLeft(mNumberA, '.')), Length(StrLeft(mNumberB, '.'))); //整数部分最大长度
  mNumberA := DupeString('0', I - Length(StrLeft(mNumberA, '.'))) + mNumberA; //整数前补0
  mNumberB := DupeString('0', I - Length(StrLeft(mNumberB, '.'))) + mNumberB; //整数前补0
  T := Max(Length(StrRight(mNumberA, '.')), Length(StrRight(mNumberB, '.'))); //小数部分最大长度
  if ((Length(StrLeft(mNumberA, '.'))) > (Length(StrLeft(mNumberB, '.')))) or(((Length(StrLeft(mNumberA, '.'))) = (Length(StrLeft(mNumberB, '.'))))and(mNumberB>mNumberA))then
  begin
    TemNumA := mNumberA;
    mNumberA := mNumberB + DupeString('0', T - Length(StrRight(mNumberB, '.'))); //小数后补0
    mNumberB := TemNumA + DupeString('0', T - Length(StrRight(TemNumA, '.'))); //小数后补0
    minus:=True;
  end
  else
  begin
    mNumberA := mNumberA + DupeString('0', T - Length(StrRight(mNumberA, '.'))); //小数后补0
    mNumberB := mNumberB + DupeString('0', T - Length(StrRight(mNumberB, '.'))); //小数后补0
    minus:=False;
  end;
  I := I + T + 1; //计算总长度//小数长度和整数长度加上小数点长度
  T := 0; //进位数初始化
  for I := I downto 1 do //从后向前扫描
    if [mNumberA[I], mNumberB[I]] <> ['.'] then begin //不是小数点时
      T := StrToIntDef(mNumberB[I], 0) - T; //累加当前数位
      T := StrToIntDef(mNumberA[I], 0) - T; //累加当前数位
      if (T<0) and (I<>1) then
      begin
        T:=T+10;
        Result := IntToStr(T mod 10) + Result; //计算当前数位上的数字
        T := -1; //计算进位数
      end
      else
      begin
        Result := IntToStr(T mod 10) + Result; //计算当前数位上的数字
        T := T div 10; //计算进位数
      end;
    end else Result := '.' + Result; //加上小数点
  if T <> 0 then Result := IntToStr(T mod 10) + Result; //处理进位数
  while Pos('0', Result) = 1 do Delete(Result, 1, 1); //排除整数前无效的0
  while Copy(Result, Length(Result), 1) = '0' do
    Delete(Result, Length(Result), 1); //排除小数后无效的0
  if Copy(Result, Length(Result), 1) = '.' then
    Delete(Result, Length(Result), 1); //排除无效小数点
  if Copy(Result, 1, 1) = '.' then Result := '0' + Result; //处理无0小数情况
  if (Result = '') then Result := '0'; //处理空字符情况
  if minus then Result:='-'+Result;
end; { InfiniteSub}

解决方案 »

  1.   

    function InfiniteDiv(mNumberA, mNumberB: string;n:integer): string; { 无限位数除法 } function vDecimal(mNumber: string):integer;
     var m,x:integer;
     begin
       x:=0;
       if Pos('.', mNumber) <= 0 then
       begin
         for m:=Length(mNumber) downto 1 do
         begin
           if mNumber[m]='0' then x:=x+1 else Break;
         end;
         Result:=-x;
       end
       else
         Result:=Length(StrRight(mNumber, '.'));
     end; function formatnum2(mNumber: string):string;
     begin
       Result:=mNumber;
       if Pos('.', Result )<= 0 then Result := Result + '.';
       Result:=StrLeft(Result,'.')+StrRight(Result,'.');
       while Pos('0', Result) = 1 do Delete(Result, 1, 1);
       while Copy(Result, Length(Result), 1) = '0' do Delete(Result, Length(Result), 1);
     end;var
      I,J,t,v,y,Len: Integer;
      TemSub,TemNum: string;
    begin
      Result := '';
      mNumberA:=formatnum(mNumberA);
      mNumberB:=formatnum(mNumberB);
      v:=vDecimal(mNumberA)-vDecimal(mNumberB);
      mNumberA:=formatnum2(mNumberA);
      mNumberB:=formatnum2(mNumberB);
      if mNumberB='' then
        Result:='Err'
      else if mNumberA='' then
        Result:='0'
      else
      begin
      I:=0;
      if Length(mNumberA)>Length(mNumberB) then
        Len:=Length(mNumberB)
      else
        Len:=Length(mNumberA);
      if Copy(mNumberA,1,Len)>Copy(mNumberB,1,Len) then
        J:=Length(mNumberB)
      else
        J:=Length(mNumberB)+1;
      for y:=1 to J do
      begin
        if Length(mNumberA)>=y then
          TemSub:=TemSub+mNumberA[y]
        else
        begin
          TemSub:=TemSub+'0';
          v:=v+1;
        end;
      end;
      while I<=n do
      begin
        if TemSub[1]>mNumberB[1] then
          t:=StrToInt(TemSub[1]) Div StrToInt(mNumberB[1])
        else
          t:=StrToInt(TemSub[1]+TemSub[2]) Div StrToInt(mNumberB[1]);
        TemNum:=InfiniteMult(mNumberB,IntToStr(t));
        while (Length(TemNum)>Length(TemSub)) or ((Length(TemNum)=Length(TemSub))and(TemNum>TemSub)) do
        begin
          t:=t-1;
          TemNum:=InfiniteMult(mNumberB,IntToStr(t));
        end;
        Result:=Result+IntToStr(t);
        I:=I+1;
        TemSub:=InfiniteSub(TemSub,TemNum);
        if TemSub='0' then
        begin
          if Length(mNumberA)<J then
            Break
          else
            TemSub:='';
        end;
        J:=J+1;
        if Length(mNumberA)>=J then
          TemSub:=TemSub+mNumberA[J]
        else
        begin
          TemSub:=TemSub+'0';
          v:=v+1;
        end;
      end;
      while Copy(Result, Length(Result), 1) = '0' do
      begin
        v:=v-1;
        Delete(Result, Length(Result), 1);
      end;
      if v>Length(Result) then
      begin
        Result:='.'+DupeString('0',v-Length(Result)) + Result;
      end
      else if v>0 then
        Insert('.', Result, Length(Result) - v + 1);
      if v<0 then Result:=DupeString('0',0-v) + Result;
      if Result[1]='.' then Result:='0'+Result;
      end;
    end; { InfiniteDiv}
      

  2.   

    if Result[1] = '.' then Result := '0' + Result;
      if Copy(Result, 1, 1) = '.' then Result := '0' + Result; //处理无0小数情况比较如上两句话!
    请用'2/1'测试
      

  3.   

    to ehom: 少量测试通过,有时间再整理整理,贴于此贴
      

  4.   

    to zswang:"if Result[1] = '.' then Result := '0' + Result;
      if Copy(Result, 1, 1) = '.' then Result := '0' + Result; //处理无0小数情况比较如上两句话!
    请用'2/1'测试"什么意思?
    有什么问题吗?是需要作改进,加上对带符号数字的计算!不过这种改进的工作量并不大!
      

  5.   

    //
      Result := '';
      if Result[1] = '.' then Result := '0' + Result; //这就出现异常了!
      

  6.   

    修正版本如下:function formatnum(mNumber: string):string;
    var
    m:integer;
    TemStr:string;
    begin
      Result:='';
      for m:=1 to Length(mNumber) do
      begin
        if mNumber[m]='.' then
          Result:=Result+'.'
        else
          Result:=Result+IntToStr(StrToIntDef(mNumber[m], 0));
      end;
      while Pos('0', Result) = 1 do Delete(Result, 1, 1); //排除整数前无效的0
      if Pos('.', Result )<= 0 then Result := Result + '.'; //没有有小数点补小数点
      TemStr:=StrRight(Result,'.');
      while Copy(TemStr, Length(TemStr), 1) = '0' do Delete(TemStr, Length(TemStr), 1); //排除小数后无效的0
      Result:=StrLeft(Result,'.')+'.'+TemStr;
      if Copy(Result, Length(Result), 1) = '.' then Delete(Result, Length(Result), 1); //排除无效小数点
      if Copy(Result, 1, 1)='.' then Result:='0'+Result;
      if (Result = '') then Result := '0';
    end;function InfiniteDiv(mNumberA, mNumberB: string;n:integer): string; { 无限位数除法 } function vDecimal(mNumber: string):integer;
     var m,x:integer;
     begin
       x:=0;
       if Pos('.', mNumber) <= 0 then
       begin
         for m:=Length(mNumber) downto 1 do
         begin
           if mNumber[m]='0' then x:=x+1 else Break;
         end;
         Result:=-x;
       end
       else
         Result:=Length(StrRight(mNumber, '.'));
     end; function formatnum2(mNumber: string):string;
     begin
       Result:=mNumber;
       if Pos('.', Result )<= 0 then Result := Result + '.';
       Result:=StrLeft(Result,'.')+StrRight(Result,'.');
       while Pos('0', Result) = 1 do Delete(Result, 1, 1);
       while Copy(Result, Length(Result), 1) = '0' do Delete(Result, Length(Result), 1);
     end;var
      I,J,t,v,y,Len: Integer;
      TemSub,TemNum: string;
    begin
      Result := '';
      mNumberA:=formatnum(mNumberA);
      mNumberB:=formatnum(mNumberB);
      v:=vDecimal(mNumberA)-vDecimal(mNumberB);
      mNumberA:=formatnum2(mNumberA);
      mNumberB:=formatnum2(mNumberB);
      if mNumberB='' then
        Result:='Err'
      else if mNumberA='' then
        Result:='0'
      else
      begin
      I:=0;
      if Length(mNumberA)>Length(mNumberB) then
        Len:=Length(mNumberB)
      else
        Len:=Length(mNumberA);
      if Copy(mNumberA,1,Len)>Copy(mNumberB,1,Len) then
        J:=Length(mNumberB)
      else
        J:=Length(mNumberB)+1;
      for y:=1 to J do
      begin
        if Length(mNumberA)>=y then
          TemSub:=TemSub+mNumberA[y]
        else
        begin
          TemSub:=TemSub+'0';
          v:=v+1;
        end;
      end;
      while I<=n do
      begin
        if TemSub[1]>mNumberB[1] then
          t:=StrToInt(TemSub[1]) Div StrToInt(mNumberB[1])
        else
          t:=StrToInt(TemSub[1]+TemSub[2]) Div StrToInt(mNumberB[1]);
        TemNum:=InfiniteMult(mNumberB,IntToStr(t));
        while (Length(TemNum)>Length(TemSub)) or ((Length(TemNum)=Length(TemSub))and(TemNum>TemSub)) do
        begin
          t:=t-1;
          TemNum:=InfiniteMult(mNumberB,IntToStr(t));
        end;
        Result:=Result+IntToStr(t);
        I:=I+1;
        TemSub:=InfiniteSub(TemSub,TemNum);
        if (TemSub='0') and (Length(mNumberA)<=J) then
        begin
          v:=v+1;
          Break;
        end;
        J:=J+1;
        if Length(mNumberA)>=J then
        begin
          TemSub:=TemSub+mNumberA[J];
        end
        else
        begin
          TemSub:=TemSub+'0';
          v:=v+1;
        end;
      end;
      v:=v-1;
      while Copy(Result, Length(Result), 1) = '0' do
      begin
        v:=v-1;
        Delete(Result, Length(Result), 1);
      end;
      if v>Length(Result) then
        Result:='.'+DupeString('0',v-Length(Result)) + Result
      else if v>0 then
        Insert('.', Result, Length(Result) - v +1);
      if v<0 then Result:=Result+DupeString('0',0-v);
      if Copy(Result, 1, 1)='.' then Result:='0'+Result;
      end;
    end; { InfiniteDiv}//第三个参数表示保留N位有效数字,能整除时以实际结果为准!
      

  7.   

    修正严重BUG一个!发生在有效数字N取值太少时!当循环结束而除法未进行完时,要在后面进行补位操作!function InfiniteDiv(mNumberA, mNumberB: string;n:integer): string; { 无限位数除法 } function vDecimal(mNumber: string):integer;
     var m,x:integer;
     begin
       x:=0;
       if Pos('.', mNumber) <= 0 then
       begin
         for m:=Length(mNumber) downto 1 do
         begin
           if mNumber[m]='0' then x:=x+1 else Break;
         end;
         Result:=-x;
       end
       else
         Result:=Length(StrRight(mNumber, '.'));
     end; function formatnum2(mNumber: string):string;
     begin
       Result:=mNumber;
       if Pos('.', Result )<= 0 then Result := Result + '.';
       Result:=StrLeft(Result,'.')+StrRight(Result,'.');
       while Pos('0', Result) = 1 do Delete(Result, 1, 1);
       while Copy(Result, Length(Result), 1) = '0' do Delete(Result, Length(Result), 1);
     end;var
      I,J,t,v,y,Len: Integer;
      TemSub,TemNum: string;
    begin
      Result := '';
      mNumberA:=formatnum(mNumberA);
      mNumberB:=formatnum(mNumberB);
      v:=vDecimal(mNumberA)-vDecimal(mNumberB);
      mNumberA:=formatnum2(mNumberA);
      mNumberB:=formatnum2(mNumberB);
      if mNumberB='' then
        Result:='Err'
      else if mNumberA='' then
        Result:='0'
      else
      begin
      I:=0;
      if Length(mNumberA)>Length(mNumberB) then
        Len:=Length(mNumberB)
      else
        Len:=Length(mNumberA);
      if Copy(mNumberA,1,Len)>=Copy(mNumberB,1,Len) then
        J:=Length(mNumberB)
      else
        J:=Length(mNumberB)+1;
      for y:=1 to J do
      begin
        if Length(mNumberA)>=y then
          TemSub:=TemSub+mNumberA[y]
        else
        begin
          TemSub:=TemSub+'0';
          v:=v+1;
        end;
      end;
      while I<=n do
      begin
        if TemSub[1]>mNumberB[1] then
          t:=StrToInt(TemSub[1]) Div StrToInt(mNumberB[1])
        else
          t:=StrToInt(TemSub[1]+TemSub[2]) Div StrToInt(mNumberB[1]);
        TemNum:=InfiniteMult(mNumberB,IntToStr(t));
        while (Length(TemNum)>Length(TemSub)) or ((Length(TemNum)=Length(TemSub))and(TemNum>TemSub)) do
        begin
          t:=t-1;
          TemNum:=InfiniteMult(mNumberB,IntToStr(t));
        end;
        Result:=Result+IntToStr(t);
        I:=I+1;
        TemSub:=InfiniteSub(TemSub,TemNum);
        if (TemSub='0') and (Length(mNumberA)<J) then
        begin
          v:=v+1;
          Break;
        end;
        if TemSub='0' then TemSub:='';
        J:=J+1;
        if Length(mNumberA)>=J then
        begin
          TemSub:=TemSub+mNumberA[J];
        end
        else
        begin
          TemSub:=TemSub+'0';
          v:=v+1;
        end;
      end;
      if Length(mNumberA)>=J then
        v:=v-(Length(mNumberA)-J)-1
      else
        v:=v-1;
      while Copy(Result, Length(Result), 1) = '0' do
      begin
        v:=v-1;
        Delete(Result, Length(Result), 1);
      end;
      if v>Length(Result) then
        Result:='.'+DupeString('0',v-Length(Result)) + Result
      else if v>0 then
        Insert('.', Result, Length(Result) - v +1);
      if v<0 then Result:=Result+DupeString('0',0-v);
      if Copy(Result, 1, 1)='.' then Result:='0'+Result;
      end;
    end; { InfiniteDiv}咳,随手写个小程序,居然有怎么多错误!最近和同学CS杀多了,对代码的感觉越来越差了!
      

  8.   

    谁能用vb实现1000的阶乘? 
    作  者:  wang_anjun (大笨猫)  
    http://expert.csdn.net/Expert/topic/1355/1355122.xml?temp=9.316653E-02
    我这几天做了一个,1000的阶乘共1986位数,用了差不多5分钟,(机器不太好)算法类似手工乘法,没用数组,全是字符串操作,发现小学乘法学的不是很好,因此断续做了好几天,不过全是上班时间,报复老板吗?有点,说实话我现在多数时间是在混,我实在讨厌老板的嘴脸,谢谢你给我出了一个有意思的题目啊!
    最大结果只要不超过64k长度都可以算出来,超过的话我要考虑别的办法