2012-03-15 36 views
7

Tôi có thể viết for..do quy trình cho giá trị số nguyên .. Nhưng tôi không thể ghi nó cho giá trị int64. Ví dụ:Tại sao tôi không thể sử dụng Int64 trong vòng lặp for?

var 
    i:int64; 
begin 
    for i:=1 to 1000 do 
end; 

Trình biên dịch từ chối biên dịch, tại sao từ chối?

+3

Xác định "vi lỗi". – simchona

+0

Tôi không thể thấy một chương trình error.also không thể bắt đầu .. – musti

+2

+1 vì đây là một câu hỏi học thuật, tôi thấy như vậy và hành vi như vậy. Tôi đã mong đợi nó hoạt động, nhưng nó không .... tại sao điều này tôi tự hỏi. Thay vì một 'Tôi thực sự cần phải làm hàng tỷ tỷ lần lặp trong vòng loại câu hỏi của tôi. – Johan

Trả lời

3

Thậm chí nếu trình biên dịch đã phép "Int64" trong một Delphi 7 cho-loop (Delphi ???), nó có thể sẽ không hoàn thành iterating qua đầy đủ cho đến khi đôi khi sau cái chết nhiệt của mặt trời.

Vậy tại sao bạn không thể sử dụng "số nguyên"?

Nếu bạn phải sử dụng giá trị int64 ... thì chỉ cần sử dụng vòng lặp "while" thay thế.

Sự cố được giải quyết :)

+0

Nhưng tôi phải làm như thế này.bởi vì tôi m bằng cách sử dụng chuỗi đó là 3 tỷ chiều dài. Làm thế nào tôi có thể viết này: cho i: = 1 đến 30000000000? – musti

+0

Sử dụng vòng lặp 'while', ví dụ:' var I: Int64; I: = 1; trong khi tôi <= 30000000000 bắt đầu ...; Inc (I); kết thúc, ' –

+1

3 tỷ chuỗi ký tự? Nghe có vẻ kỳ lạ khi làm việc cùng. –

9

Trình biên dịch Delphi đơn giản không hỗ trợ bộ đếm vòng Int64.

5

Bộ đếm vòng lặp trong một số for loop phải là số nguyên (hoặc nhỏ hơn).
Đây là một tối ưu hóa để tăng tốc độ thực thi vòng lặp for.

Nội bộ Delphi luôn sử dụng Int32, vì trên x86 đây là kiểu dữ liệu nhanh nhất hiện có.
Đây là tài liệu ở đâu đó sâu trong hướng dẫn sử dụng, nhưng tôi không có một liên kết hữu ích ngay bây giờ.

Nếu bạn phải có bộ đếm vòng lặp 64 bit, hãy sử dụng vòng lặp while..do hoặc repeat..until.

2

Tại sao sử dụng Int64 trên vòng lặp for?

dễ dàng để trả lời:

  • Không cần phải làm rất nhiều lần lặp cần một Int64, chỉ cần làm một vòng lặp từ 5E9 để 5E9 + 2 (ba lần lặp trong tổng số).
  • Nó chỉ là giá trị trên lặp lớn hơn so với những gì Int32 thể giữ

Một ví dụ:

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; 

Đó là mã sẽ mất không có thời gian ở tất cả, nó chỉ là giá trị chỉ số cần phải vượt quá giới hạn số nguyên 32 bit.

Giải pháp là để làm điều đó với một vòng lặp 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; 

Vậy tại sao các trình biên dịch từ chối để biên dịch các vòng lặp foor, tôi thấy không có lý do thực sự ... bất kỳ vòng lặp for có thể được tự động dịch sang một vòng lặp while ... và pre-compiler có thể làm như vậy trước khi trình biên dịch (giống như các tối ưu hóa khác được thực hiện) ... lý do duy nhất tôi thấy là những người lười biếng tạo trình biên dịch mà không nghĩ về nó.

Nếu được tối ưu hóa và vì vậy chỉ có thể sử dụng chỉ mục 32 bit, nếu mã cố gắng sử dụng chỉ mục 64 bit thì không thể tối ưu hóa được, vậy tại sao không để trình tối ưu hóa biên dịch trước chage cho chúng tôi ... nó chỉ mang lại hình ảnh xấu cho các lập trình viên !!!

Tôi không muốn làm cho bất cứ ai ungry ...

Tôi chỉ nói điều gì đó rõ ràng ...

Bằng cách này, không phải tất cả mọi người bắt đầu một vòng lặp foor trên không (hoặc một) giá trị ... đôi khi có sự cần thiết phải bắt đầu nó trên các giá trị thực sự rất lớn.

Nó được allways nói rằng nếu bạn cần phải làm điều gì đó một số cố định lần bạn sử dụng tốt nhất cho vòng lặp thay vì vòng lặp while ...

Ngoài ra tôi có thể nói điều gì đó ... hai phiên bản như vậy, for-loop và vòng lặp while sử dụng Inc (Index) đều nhanh như nhau ... nhưng nếu bạn đặt bước lặp while như Index: = Index + 1; nó chậm hơn; nó thực sự là không chậm hơn vì trước biên dịch optimizator thấy và sử dụng Inc (Index) thay vì ... bạn có thể thấy nếu mua làm tiếp theo:

// 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; 

Các ưu hoa có thể nhìn thấy một biến không thay đổi giá trị của nó, do đó, nó có thể chuyển đổi nó thành hằng số, sau đó tăng phân bổ nếu thêm hằng số (biến: = biến + hằng số), nó sẽ tối ưu hóa nó thành Inc (biến, hằng số) và trong trường hợp nó thấy hằng số như vậy là 1 nó cũng sẽ optimes nó để Inc (biến) ... và optimizatons như vậy trong ngôn ngữ máy tính cấp thấp là rất noticeble ...

Trong ngôn ngữ máy tính cấp thấp: Một bình thường thêm (biến: = variable1 + variable2) ngụ ý hai lần đọc bộ nhớ cộng một số tiền cộng bộ nhớ điện tử viết ... rất nhiều công việc Nhưng nếu là một (biến: = biến + othervariable) nó có thể được tối ưu hóa giữ biến bên trong bộ nhớ cache xử lý. Ngoài ra nếu nó là (biến: = biến1 + hằng số) nó cũng có thể được tối ưu bằng cách giữ hằng số trên bộ nhớ cache của bộ xử lý Và nếu nó là (biến: = biến + hằng) cả hai đều được lưu trữ trên bộ nhớ cache của bộ xử lý với các tùy chọn khác, không cần đến RAM.

Bằng cách như vậy trước khi biên dịch tối ưu hóa làm khác tối ưu hóa quan trọng ... cho-vòng biến chỉ số được holded như đăng ký xử lý ... nhanh hơn nhiều hơn so với bộ xử lý bộ nhớ cache ...

xử lý mẹ Hầu hết làm thêm tối ưu hóa (ở cấp độ phần cứng, bên trong bộ xử lý) ... một số vùng nhớ cache (biến 32 bit cho chúng ta) thấy được sử dụng intensivly được lưu trữ như thanh ghi đặc biệt để gắn chặt truy cập ... và vòng lặp for-loop/while-loop chỉ số là những người trong số họ ... nhưng như tôi đã nói .. hầu hết các nhà kiểm tra AMD mẹ (những người sử dụng công nghệ MP nào đó) ... tôi chưa biết bất kỳ Intel làm điều đó !!! tối ưu hóa như vậy là có liên quan hơn khi đa lõi và trên siêu máy tính ... vì vậy có lẽ đó là lý do tại sao AMD có nó và Intel không !!!

Tôi chỉ muốn hiển thị một "lý do", có nhiều hơn ... một số khác có thể đơn giản như chỉ mục được lưu trữ trên loại trường Int64 cơ sở dữ liệu, v.v ... có rất nhiều lý do tôi biết và nhiều hơn nữa tôi chưa biết ...

Tôi hy vọng điều này sẽ giúp hiểu được nhu cầu thực hiện vòng lặp trên chỉ mục Int64 và cách thực hiện mà không mất tốc độ bằng cách chuyển đổi vòng lặp thành một cách chính xác một vòng lặp while.

Lưu ý: Đối với biên dịch x86 (không phải để biên dịch 64 bit) hãy cẩn thận rằng Int64 được quản lý nội bộ dưới dạng hai phần Int32 ... và khi sửa đổi giá trị có một mã bổ sung để thực hiện, trên bổ sung và dưới nó rất thấp, nhưng trên số nhân hoặc phân số như vậy là đáng chú ý ...nhưng nếu bạn thực sự cần Int64 bạn cần nó, vì vậy những gì khác để làm ... và tưởng tượng nếu bạn cần phao hoặc đôi, vv ... !!!

Các vấn đề liên quan