我可以寫for..do
進程的整數值.. 但我不能寫它的int64值。 例如:爲什麼我不能在for循環中使用Int64?
var
i:int64;
begin
for i:=1 to 1000 do
end;
編譯器拒絕編譯這個,它爲什麼拒絕呢?
我可以寫for..do
進程的整數值.. 但我不能寫它的int64值。 例如:爲什麼我不能在for循環中使用Int64?
var
i:int64;
begin
for i:=1 to 1000 do
end;
編譯器拒絕編譯這個,它爲什麼拒絕呢?
即使編譯器做允許「的Int64」德爾福7環(德爾福 ???),它可能會通過全方位的不完整的迭代,直到某個熱死後太陽。
那麼,爲什麼你不能只使用「整數」?
如果你必須使用int64的值...那麼只需使用「while」循環來代替。
問題解決了:)
但我必須這樣做,因爲我使用的字符串是30億長度。如何寫這個:對於我:= 1到30000000000? – musti 2012-03-15 21:51:15
使用'while'循環,例如:'var I:Int64; I:= 1;而我<= 30000000000確實開始......;公司(I);結束;' – 2012-03-15 23:06:54
30億字符串?聽起來很奇怪。 – 2012-03-15 23:17:48
的Delphi編譯器根本不支持的Int64循環計數器呢。
for loop
中的循環計數器必須是整數(或更小)。
這是一個優化,以加快執行for
循環。
內部Delphi總是使用Int32,因爲在x86上這是可用的最快的數據類型。
這是記錄在手冊的深處,但我現在沒有方便的鏈接。
如果必須有64位循環計數器,使用while..do
或repeat..until
循環。
爲什麼要在for-loop上使用Int64?
容易回答:
一個例子更大:
procedure Why_Int64_Would_Be_Great_On_For_Loop;
const
StartValue=5000000000; // Start form 5E9, 5 thousand millons
Quantity=10; // Do it ten times
var
Index:Int64;
begin
for Index:=StartValue to StartValue+Quantity-1
do begin // Bla bla bla
// Do something really fast (only ten times)
end;
end;
該代碼會採取任何時候都,它只是索引值需要遠遠超過32位整數限制。
的解決方案是用一個while循環來做到這一點:
procedure Equivalent_For_Loop_With_Int64_Index;
const
StartValue=5000000000; // Start form 5E9, 5 thousand millons
Quantity=10; // Do it ten times
var
Index:Int64;
begin
Index:=StartValue;
while Index<=StartValue+Quantity
do begin // Bla bla bla
// Do something really fast (only ten times)
Inc(Index);
end;
end;
那麼爲什麼編譯器拒絕編譯福爾循環,我認爲沒有真正的理由......任何for循環,可以自動翻譯成一個while循環......並且預編譯器可以在編譯器之前這樣做(就像完成其他優化一樣)......我看到的唯一原因是創建編譯器的懶惰的人沒有想到它。
如果for是優化的,所以它只能使用32位索引,那麼如果代碼嘗試使用64位索引,它不能被如此優化,那麼爲什麼不讓預編譯器優化器爲我們改變......它只會給程序員帶來不好的形象!
我不想讓任何人ungry ...
我只說幾句話明顯...
順便說,並不是所有的人開始零(或一個)值的福爾循環...有時需要以真正巨大的價值開始它。
據永諾說,如果你需要做的事情的固定次數你循環而不是while循環最好使用...
此外,我能說些什麼......這樣的兩個版本, for循環和使用Inc(Index)的while循環同樣快速......但是如果您將while循環步驟設置爲Index:= Index + 1;它比較慢;這是真的不慢,因爲預編譯optimizator看到並使用公司(指數),而不是...你可以看到,如果買在做下一個:
// I will start the loop from zero, not from two, but i first do some maths to avoid pre-compiler optimizator to convert Index:=Index+Step; to Inc(Index,Step); or better optimization convert it to Inc(Index);
Index:=2;
Step:=Index-1; // Do not put Step:=1; or optimizator will do the convertion to Inc()
Index:=Step-2; // Now fix, the start, so loop will start from zero
while Index<1000000 // 1E6, one millon iterations, from 0 to 999999
do begin
// Do something
Index:=Index+Step; // Optimizator will not change this into Inc(Index), since sees that Step has changed it's value before
end;
優化可以看到一個變量不改變它的價值,所以它可以將其轉換爲一個常量,然後在增量賦值時添加一個常量(變量:=變量+常量),它將優化到Inc(變量,常量),並且在它看到這個常量爲1的情況下,它也會optimes它來公司(可變)...和在低的水平的計算機語言例如optimizatons非常都明顯...
在低電平計算機語言: 一個正常的加載(變量:=變量1 +變量2)意味着兩個存儲器讀取加上一筆總和e memory memory ...很多工作 但是如果是(變量:=變量+其他變量),它可以在處理器緩存內優化保持變量。 此外,如果它是一個(變量:=變量1 +常量),它也可以通過在處理器緩存上保持常量來優化 如果它是(變量:=變量+常量),則緩存在處理器緩存上,與其他選項一樣,不需要訪問RAM。
在這種方式預編譯器優化做的另一個重要的優化... for循環索引變量holded者處理器寄存器...比處理器高速緩存更快更多...
大多數母親處理器做一個額外的優化(在硬件級別,在處理器內部)......一些被強制使用的緩存區域(我們的32位變量)被存儲爲特殊的寄存器以緊固訪問......並且這樣的for-loop/while-loop索引就是其中之一...但正如我所說的......大多數母親的AMD處理器(使用MP技術的處理器都是這樣做的)......我還不知道有哪個英特爾這樣做!這樣的優化在多核和超級計算時更具相關性......所以也許這就是AMD爲什麼會這麼做的原因,而英特爾不是!
我只想顯示一個「爲什麼」,還有更多...另一個可以像索引存儲在數據庫Int64字段類型等一樣簡單...有很多原因我知道,還有更多我還不知道......
我希望這將有助於瞭解需要做一個Int64索引上的循環,以及如何做到這一點,而不會因爲正確高效地將循環轉換爲一個while循環。
注意:對於x86編譯(不適用於64位編譯)請注意,Int64在內部作爲兩個Int32部件進行管理......並且在修改值時需要額外的代碼,在增加和下降時它非常低,但在乘法或分裂這種額外的是很明顯的...但是如果你真的需要Int64,那麼還有什麼可以做的......並且想象一下,如果你需要float或者double等等...... !!!
定義「en error」。 – simchona 2012-03-15 21:38:30
我不能看到一個error.also程序無法啓動.. – musti 2012-03-15 21:46:40
+1,因爲這是一個學術問題,我看到某某行爲。我會預料到它的工作,但它不......這是我爲什麼想知道。而不是'我真的需要在我的循環中做數萬億次的迭代'這種問題。 – Johan 2012-03-16 11:59:10