-2147483648
không phải là số nguyên; đó là một biểu thức gồm một toán tử -
đơn nhất áp dụng cho chữ số 2147483648
.
Trước tiêu chuẩn C++ 2011 mới, C++ không yêu cầu sự tồn tại của bất kỳ loại nào lớn hơn 32 bit (C++ 2011 thêm long long
), vì vậy, 2147483648
là không thể di chuyển.
Một số nguyên thập phân đen là những người đầu tiên của các loại sau đây, trong đó giá trị của nó phù hợp:
int
long int
long long int (new in C++ 2011)
Lưu ý rằng không bao giờ là của một loại unsigned trong tiêu chuẩn C++. Trong các phiên bản năm 1998 và 2003 của tiêu chuẩn C (không có long long int
), một chữ số nguyên thập phân quá lớn để phù hợp với long int
dẫn đến hành vi không xác định. Trong C++ 2011, nếu một số nguyên thập phân không phù hợp trong long long int
, thì chương trình là "không đúng định dạng".
Nhưng gcc (ít nhất là bản phát hành 4.6.1, phiên bản mới nhất tôi có) không triển khai ngữ nghĩa C++ 2011. Các chữ số 2147483648
, không phù hợp với độ dài 32 bit, được coi là unsigned long
, ít nhất là trên hệ thống 32 bit của tôi. (Đó là tốt cho C++ 98 hoặc C++ 2003, hành vi là không xác định, do đó, trình biên dịch có thể làm bất cứ điều gì nó thích.)
Vì vậy, cho một điển hình 32-bit 2's-bổ sung int
loại, này:
cout << -2147483647 << '\n';
lấy int
giá trị 2147483647
, phủ nhận nó, và in kết quả, mà phù hợp với kết quả toán học mà bạn mong đợi . Nhưng điều này:
cout << -2147483648 << '\n';
(khi biên dịch với gcc 4.6.1) lấy long
hoặc unsigned long
giá trị 2147483648
, phủ nhận nó như một unsigned int, năng suất 2147483648
, và in đó.
Như những người khác đã đề cập, bạn có thể sử dụng hậu tố để buộc một loại cụ thể.
Dưới đây là một chương trình nhỏ mà bạn có thể sử dụng để hiển thị như thế nào xử lý biên dịch của bạn literals:
#include <iostream>
#include <climits>
const char *type_of(int) { return "int"; }
const char *type_of(unsigned int) { return "unsigned int"; }
const char *type_of(long) { return "long"; }
const char *type_of(unsigned long) { return "unsigned long"; }
const char *type_of(long long) { return "long long"; }
const char *type_of(unsigned long long) { return "unsigned long long"; }
int main()
{
std::cout << "int: " << INT_MIN << " .. " << INT_MAX << "\n";
std::cout << "long: " << LONG_MIN << " .. " << LONG_MAX << "\n";
std::cout << "long long: " << LLONG_MIN << " .. " << LLONG_MAX << "\n";
std::cout << "2147483647 is of type " << type_of(2147483647) << "\n";
std::cout << "2147483648 is of type " << type_of(2147483648) << "\n";
std::cout << "-2147483647 is of type " << type_of(-2147483647) << "\n";
std::cout << "-2147483648 is of type " << type_of(-2147483648) << "\n";
}
Khi tôi biên dịch nó, tôi nhận được một số cảnh báo:
lits.cpp:18:5: warning: this decimal constant is unsigned only in ISO C90
lits.cpp:20:5: warning: this decimal constant is unsigned only in ISO C90
và đầu ra sau, thậm chí với gcc -std=c++0x
:
int: -2147483648 .. 2147483647
long: -2147483648 .. 2147483647
long long: -9223372036854775808 .. 9223372036854775807
2147483647 is of type int
2147483648 is of type unsigned long
-2147483647 is of type int
-2147483648 is of type unsigned long
Tôi nhận được kết quả tương tự với VS2010, ít nhất với defau lt cài đặt.
Thú vị, đây là cách tháo gỡ: cout << -4294967293 << '\ n'; đẩy 0Ah mov esi, esp đẩy 3 Lưu ý rằng nó đẩy 3 ngay lập tức. (VS2010 cuối cùng) – ScarletAmaranth
Nhà điều hành luồng của 'std :: cout' có lẽ không quảng cáo những chữ như bạn mong đợi. – AJG85
@ScarletAmaranth Tôi nghĩ rằng đó là ok, bởi vì 4294967293 lần đầu tiên được đọc là int unsigned và hơn negated mà sản lượng 3. Không hoàn toàn chắc chắn mặc dù – hirschhornsalz