为什么使用sqr求平方时,超过8位的数结果不对
解决方案 »
- DELPHI+mysql
- 紧急:create一个Form后,该Form关闭,close事件caFree了,可是为什么assigned(myFormvar)还是为true呢?
- socket 问题,怎么绑定源(本地主机ip地址)高分求教!!!!
- 如何使SPEEDBUTTON上的图标在 Enable:=False 变为凹陷的效果
- 关于listbox的问题?
- 菜鸟问题:怎样去掉 菜单项带的快捷键?
- 一个大家都可以拿分的问题
- 动态链接库 在线等待,立即结贴 敬请各位大侠指点
- 三层从表数据怎么样添加
- paradox转化为mssql2000怎么搞?
- IT职业交流--山东
- 怎么把DELPHI的子窗口图标显示在工具栏?
我用 s:= x*x;也不行
晕 用int64或者real数据类型就可以了 撒
integer范围-2147483648--2147483647
lw := sqr(i);结果: 559810353
lw := sqr(i);结果: 559810353
int64也不是万能的,最大只到2的63次方而已
2^63 =9223372036854775808
123456789012345^2=15241578753238669120562399025
远远超出了
我不知道你求这么大数的平方来干嘛
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
不知道对不对
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的数组中就可以了,存储格式是从数组的后部存起,不足位数的补零。
在按钮事件中添加
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)));
已经解决
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 }
呵呵,是我没有描述清楚。
程序应该没有什么错误。
之所以大数不行,是因为我在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
//*************************//
你还有很多函数没有传代码上来啊。
{ 无限位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 }
{ 无限位数减法 }
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;