2014-07-08 30 views
6

Tôi có một dự án mà tôi xử lý các số lớn (ns-timestamps) không vừa với số nguyên. Do đó, tôi muốn sử dụng ví dụ: int64_t và hiện đang viết một trường hợp thử nghiệm (có!).Định nghĩa giá trị số nguyên lớn

Để kiểm tra hành vi cho số lượng lớn, tôi bắt đầu với cái gì đó như

int64_t val = 2*std::numeric_limits<int>::max(); 
qDebug() << "long val" << val; 

trả về

long val -2 

(giống như nếu tôi xác định val như int).

Nhưng nếu tôi viết

int64_t val = std::numeric_limits<int>::max(); 
val *= 2; 
qDebug() << "long val" << val; 

tôi nhận được

long val 4294967294 

đó có vẻ đúng.

Vì vậy, đối với tôi có vẻ như là 2*max() được lưu trữ lần đầu tiên trong một số nguyên (cắt ngắn trong bước này) và sau đó được sao chép vào int64. Lý do tại sao điều này xảy ra? Trình biên dịch biết rằng kết quả là loại int64 sao cho nó 2*max() phải phù hợp trực tiếp.

Trả lời

5

Vì vậy, đối với tôi nó trông như thể 2*max() được lưu trữ đầu tiên trong một số nguyên (rút ngắn trong bước này) và sau đó sao chép vào int64

này là hoàn toàn chính xác. Theo đặc tả ngôn ngữ, khi tất cả các phần của một biểu thức phù hợp trong một int, việc tính toán được thực hiện bằng số nguyên. Trong trường hợp của bạn, cả hai số 2max() đều phù hợp với một số int, do đó phép nhân được thực hiện bằng số nguyên, gây tràn.

Trình biên dịch biết rằng kết quả là loại int64 sao cho nó là 2*max() phải khớp trực tiếp.

Kết quả mà biểu thức được chỉ định không quan trọng trong trường hợp này: biểu thức chính nó hướng theo cách được tính toán. Bạn có thể đạt được kết quả tương tự bằng cách truyền số max() tới int64:

int64_t val = 2*(int64_t)std::numeric_limits<int>::max(); 
Các vấn đề liên quan