因數值過大而無法以Integer等型態存取的解決方式 |
|
pprayer
高階會員 發表:35 回覆:185 積分:174 註冊:2002-03-13 發送簡訊給我 |
有時候遇到些要運算數值過大,會超過Integer等型態能容納的範圍,
記得之前曾經在站上看到其他前輩討論過類似的問題,可是站上的文章好多,實在不容易找到。
因此想到用陣列的方式來解決。以下是以100!(100*99*98*...*2*1)來試作。
想法是將各位數,從最大的位數各自相乘後,再一一相加並且進位。 var totalary : array of integer;
addary : array of integer;
i,j,A,B,X,Y,sum : integer; begin
//本想依照位數的多寡再慢慢增加陣列的長度,
//但數次Setlength會出現錯誤...
setlength(totalary,160);
setlength(addary,160);
for i := 0 to 159 do
begin
totalary[i] := 0;
addary[i] := 0;
end; //100*99 = 9900
totalary[0] := 0;
totalary[1] := 0;
totalary[2] := 9;
totalary[3] := 9;
i := 98;
repeat
j := Length(totalary);
for j := Low(addary) to High(addary) do
addary[j] := 0;
//A為乘數的十位數,B為個位數
if i < 10 then
A := 0
else
A := i div 10;
B := i mod 10;
//各位數一一相乘並且相加 EX:
// 9 9 0 0
// x 9 8
// -------------------
// 8 1 0 0 0 0
// 8 1 0 0 0
// 7 2 0 0 0
// 7 2 0 0
// ---------------------
for j := High(totalary) downto Low(totalary) do
begin
addary[j 1] := addary[j 1] totalary[j]*A;
addary[j] := addary[j] totalary[j]*B;
end;
for j := low(totalary) to high(totalary) do
totalary[j] := 0;
// 相加之後把該進位的進位
// 8 1 0 0 0 0
// 8 1 0 0 0
// 7 2 0 0 0
// 7 2 0 0
// ---------------------
// 8 16 10 2 0 0
//→ 9 7 0 2 0 0
for j := Low(addary) to High(addary) do
begin
X := addary[j] div 10;
Y := addary[j] mod 10;
totalary[j] := totalary[j] y;
if totalary[j] >= 10 then
begin
if j = High(totalary) then
begin
SetLength(totalary,j 2);
totalary[j 1]:=0;
end;
X := X (totalary[j] div 10);
totalary[j] := totalary[j] mod 10;
end;
totalary[j 1] := totalary[j 1] X ;
end;
dec(i);
until i = 1;
sum := 0; //這是所有位數的加總
for i:= low(totalary) to High(totalary) do
begin
sum := sum totalary[i];
end;
Edit1.Text := inttostr(sum);
end;
|
P.D.
版主 發表:603 回覆:4038 積分:3874 註冊:2006-10-31 發送簡訊給我 |
|
pprayer
高階會員 發表:35 回覆:185 積分:174 註冊:2002-03-13 發送簡訊給我 |
|
P.D.
版主 發表:603 回覆:4038 積分:3874 註冊:2006-10-31 發送簡訊給我 |
引言:不過依你的做法, 有一個予盾點就是, 就是不論你用什方法來取得最大值 最後相加後仍然存入一個宣告interger的變數, 那不是還受制於這條規定 要不就改宣告為 extened, 或 double, variant 來做做看!引言: 如果把 integer 改為 int64 宣告, 是否可以解決你的過大數字問題?您好。 int64我之前試,大部分的情況都可以用。 若如上面提的100!的話 Cnt := 1; i := 100; Repeat Cnt := Cnt * i; Dec(i); until i=1; 大約i<90之後就無法算了 |
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |