Delphi超大数字运算方法

减小字体 增大字体 作者:佚名  来源:转载  发布时间:2011-06-01 11:34:46

网络收集,仅供参考!

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 Copy(Result, 1, 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][2][3][4]下一页

  function InfiniteDiv(mNumberA, mNumberB: string; n: integer): string;
{ 无限位数除法 }
// n为有效数字个数

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); // 排除整数前无效的0
  while Copy(Result, Length(Result), 1) = '0' do
    Delete(Result, Length(Result), 1); // 排除小数后无效的0
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 - 1 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; // 小数前面补0
  end;
end; { InfiniteDiv }

Tags:

作者:佚名
  • 好的评价 如果您觉得此文章好,就请您
      0%(0)
  • 差的评价 如果您觉得此文章差,就请您
      0%(0)

文章评论评论内容只代表网友观点,与本站立场无关!

   评论摘要(共 0 条,得分 0 分,平均 0 分) 查看完整评论

广告位置B