为什么使用sqr求平方时,超过8位的数结果不对

解决方案 »

  1.   

    那有其他实现方法吗
    我用 s:= x*x;也不行
      

  2.   


    晕 用int64或者real数据类型就可以了 撒
    integer范围-2147483648--2147483647
      

  3.   

    i,lw:Int64;   i:=StrToInt64('123456789012345');
       lw := sqr(i);结果: 559810353
      

  4.   

    i,lw:longword;   i:=StrToInt64('123456789012345');
       lw := sqr(i);结果: 559810353
      

  5.   

    注意数据类型
    int64也不是万能的,最大只到2的63次方而已
    2^63             =9223372036854775808
    123456789012345^2=15241578753238669120562399025
    远远超出了
    我不知道你求这么大数的平方来干嘛
      

  6.   

    delphi里进行大数的运算,一般都是定义一个 Array [0..20000-1] of byte 类型的变量然后按位运算
      

  7.   

    用POWER啊,
    procedure TForm1.Button1Click(Sender: TObject);
    var
        temp1,temp2:Extended;
    begin
        temp1:=StrToFloat(Edit1.Text);
        temp2:=Power(temp1,2);
        edit1.Text:=FloatToStr(temp2);
    end;
    123456789012345 结果是1.52415787532387E28
    不知道对不对
      

  8.   

    //定义部分
    const
      MaxBit = 100;
    type
      IntArray = array [0..MaxBit] of integer;
    //函数部分
    function PutInttoArray(Aint: integer):IntArray;
    var
        Quotient: integer;
        Remainder: integer;
        InsertPos: integer;
        Rtv: IntArray;
    begin
        InsertPos:= MaxBit;
        FillChar(Rtv,Sizeof(Rtv),0);
        while true do
        begin
          Remainder:= Aint div 10;
          Quotient:= Aint mod 10;
          Rtv[InsertPos] := Quotient;
          Dec(InsertPos);
          if (InsertPos < 0) then
          begin
          //越界,分配的数组长度不够
            Rtv[0]:= -1;
            break;
          end;
          Aint:= Remainder;
          if (Aint<=0) then break;
        end;
        Result:= Rtv;
    end;function IntArraytoStr(Aintar: IntArray):string;
    var
        Rtv: string;
        HiBit: integer;
        i: integer;
    begin
        HiBit:=High(Aintar)+1;
        for i:=1 to High(Aintar) do
        begin
          if (Aintar[i] = 0) then continue;
          HiBit:= i;
          break;
        end;
        Rtv:= '';
        for i:=HiBit to High(Aintar) do
        begin
          Rtv:= Rtv + inttostr(Aintar[i]);
        end;
        Result:= Rtv;
    end;function IntArrayMulSingle(Aintar: IntArray; ASingle: integer):IntArray;
    var
        ARtv: IntArray;
        ACarry: integer;
        AProduct: integer;
        AQuoti: integer;
        ArHigh: integer;
        HiBit: integer;
        i: integer;
    begin
        ArHigh:= High(Aintar);
        HiBit:= ArHigh+1;
        for i:=1 to ArHigh do
        begin
          if (Aintar[i] = 0) then continue;
          HiBit:= i;
          break;
        end;
        //HiBit为最先出现的不为零的数字所在数组中的位置
        ACarry:= 0;
        FillChar(ARtv,sizeof(ARtv),0);
        for i:= ArHigh downto HiBit do
        begin
          AProduct:= Aintar[i] * ASingle;
          AProduct:= AProduct + ACarry;
          AQuoti:= AProduct mod 10;
          ACarry:= AProduct div 10;
          ARtv[i]:= AQuoti;
        end;
        ARtv[HiBit-1]:=ACarry;
        if ((HiBit=1) and (ACarry<>0)) then
        begin
          ARtv[0]:= -1;
        end;
        Result:= ARtv;
    end;function IntArrayAdds(Aintar1,Aintar2: IntArray):IntArray;
    var
        ARtv: IntArray;
        ACarry: integer;
        AProduct: integer;
        AQuoti: integer;
        ArHigh1,ArHigh2: integer;
        HiBit,HiBit1,HiBit2: integer;
        i: integer;
    begin
        //求出数组1的最高有效位
        ArHigh1:= High(Aintar1);
        HiBit1:= ArHigh1+1;
        for i:=1 to ArHigh1 do
        begin
          if (Aintar1[i] = 0) then continue;
          HiBit1:= i;
          break;
        end;
        //求出数组2的最高有效位
        ArHigh2:= High(Aintar2);
        HiBit2:= ArHigh2+1;
        for i:=1 to ArHigh2 do
        begin
          if (Aintar2[i] = 0) then continue;
          HiBit2:= i;
          break;
        end;
        //获得数组1、2的最高有效位
        if (HiBit1 <= HiBit2) then HiBit:= HiBit1
        else HiBit:= HiBit2;
        //从数组最后段起累加和,类似于正常的加法运算
        ACarry:= 0;
        FillChar(ARtv,sizeof(ARtv),0);
        for i:= ArHigh1 downto HiBit do
        begin
          AProduct:= AIntar1[i]+AIntar2[i];
          AProduct:= AProduct + ACarry;
          AQuoti:= AProduct mod 10;
          ACarry:= AProduct div 10;
          ARtv[i]:= AQuoti;
        end;
        ARtv[HiBit-1]:=ACarry;
        if ((HiBit=1) and (ACarry<>0)) then
        begin
          ARtv[0]:= -1;
        end;
        Result:= ARtv;
    end;function IntArrayLeftShift(Aintar: IntArray; LSDistance: Byte):IntArray;
    var
        ARtv: IntArray;
        ArHigh: integer;
        HiBit: integer;
        i: integer;
    begin
        ArHigh:= High(Aintar);
        HiBit:= ArHigh+1;
        for i:=1 to ArHigh do
        begin
          if (Aintar[i] = 0) then continue;
          HiBit:= i;
          break;
        end;
        if (LSDistance > HiBit-1) then
        begin
        //越界,分配的数组长度不够
          FillChar(ARtv,sizeof(ARtv),0);
          ARtv[0]:=-1;
        end
        else
        begin
          FillChar(ARtv,sizeof(ARtv),0);
          for i:=HiBit to ArHigh do
          begin
            ARtv[i-LSDistance]:=Aintar[i];
          end;
        end;
        Result:= ARtv;
    end;function BigSqrt(BaseInt: IntArray):IntArray;
    var
        ARtv: IntArray;
        ArHigh: integer;
        HiBit: integer;
        Multi: integer;
        i: integer;
    begin
        ArHigh:= High(BaseInt);
        HiBit:= ArHigh+1;
        for i:=1 to ArHigh do
        begin
          if (BaseInt[i] = 0) then continue;
          HiBit:= i;
          break;
        end;
        //HiBit为最先出现的不为零的数字所在数组中的位置
        FillChar(ARtv,sizeof(ARtv),0);
        for i:=ArHigh downto HiBit do
        begin
          Multi:= BaseInt[i];
          ARtv:= IntArrayAdds(ARtv,IntArrayLeftShift(IntArrayMulSingle(BaseInt,Multi),(ArHigh-i)));
        end;
        Result:= ARtv;
    end;
    //**********************************//
    呵呵,下午写的。
    只要调用BigSqrt(BaseInt: IntArray); 同时将作为底的数保存到IntArray的数组中就可以了,存储格式是从数组的后部存起,不足位数的补零。
      

  9.   

    例如:123456789的平方没问题。
    在按钮事件中添加
    var
        Aint: integer;
        Aintar: IntArray;
    begin
        Aint:= strtointdef(Edit1.Text,$7FFFFFFF);
        Aintar:= PutInttoArray(Aint);
        //可以不通过这种方式,直接将Aintar数组中添入相应的数字
        if (Aintar[0]= -1) then
        begin
          Memo1.Lines.Add('Error!');
          Exit;
        end;
        Memo1.Lines.Add(IntArraytoStr(BigSqrt(Aintar)));
      

  10.   

    非常感谢 -----“abc3000(想想就烦)”    用大数乘法做吧 
     
     
    已经解决
    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 }
      

  11.   

    To: Blakhawk(黑鹰) 
    呵呵,是我没有描述清楚。
    程序应该没有什么错误。
    之所以大数不行,是因为我在Aint:= strtointdef(Edit1.Text,$7FFFFFFF);这句话中限定了最大的值就是$7FFFFFFF。
    把显示部分改为下面的程序段就没什么问题了:)
    //***********************//
    var
        //Aint: integer;
        Aintar: IntArray;
        BitLen: integer;
        i: integer;
    begin
        //Aint:= strtointdef(Edit1.Text,$7FFFFFFF);
        //Aintar:= PutInttoArray(Aint);
        //可以不通过这种方式,直接将Aintar数组中添入相应的数字
     //如下:
        BitLen:= Length(Edit1.Text);
        FillChar(Aintar,sizeof(Aintar),0);
        if BitLen > MaxBit then Aintar[0]:= -1
        else
        begin
          for i:= 1 to BitLen do
          begin
            Aintar[MaxBit-BitLen+i]:= strtoint(Edit1.Text[i]);
          end;
        end;    if (Aintar[0]= -1) then
        begin
          Memo1.Lines.Add('Error!');
          Exit;
        end;
        Memo1.Lines.Add(IntArraytoStr(BigSqrt(Aintar)));
    end;
    //*************************//
    9876543210987654321 通过程序算得的结果是 97546105798506325256774881877789971041
    //*************************//
      

  12.   

    TO  meil() 
      你还有很多函数没有传代码上来啊。
      

  13.   

    function StrLeft(const mStr: string; mDelimiter: string): string;
    { 无限位StrLeft函数 }
    begin  Result := Copy(mStr, 1, Pos(mDelimiter, mStr) - 1);end; { StrLeft }function StrRight(const mStr: string; mDelimiter: string): string;
    { 无限位StrRight函数 }
    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 }
      

  14.   

    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}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}function InfiniteSqr(mNumberA: string): string;
    { 无限位数乘方 }
    begin
      result :=InfiniteMult(mNumberA, mNumberA);
    end;