Tôi đã cố gắng tập thể dục KR 2.1 - xác định phạm vi của long
biến bằng cách tính toán trực tiếp.Khi dịch chuyển trái không giống như nhân với 2
#include <stdio.h>
#include <limits.h>
int main()
{
unsigned short long_bits = sizeof(long) * CHAR_BIT;
printf("LONG_MAX = %ld\n", (1L << (long_bits - 1)) - 1);
printf("LONG_MIN = %ld\n", (-1) * (1L << (long_bits - 1)));
printf("ULONG_MAX (1) = %lu\n", (1UL << long_bits) - 1); // doesn't work
printf("ULONG_MAX (2) = %lu\n", 2*(1UL << (long_bits - 1)) - 1); // work
printf("\n");
}
ULONG_MAX (1) = 0
là sai bởi vì sự thay đổi tràn trái Tôi cho rằng.ULONG_MAX (2) = 18446744073709551615
dường như đúng bằng cách thay thế sự thay đổi cuối cùng bên trái với một nhân với 2.
Vì vậy, có vẻ như nhà điều hành dịch trái bị tràn, nhưng nhân không? Tính toán trung gian này có 2*(1UL << (long_bits - 1))
quảng cáo cho một số loại hơn long
không? Trong máy của tôi, long
và long long
hoàn toàn giống nhau (8 byte).
Edit: Như Lundin chỉ ra, tất cả cần thiết cho ULONG_MAX
là printf("ULONG_MAX = %lu\n", ~0L);
Sử dụng dịch trái trong trường hợp này gây ra UB, và nhân với 2 là khả năng UB, quá (mặc dù kết quả của trường hợp 2 hình chính xác).
Theo quy tắc chung: số học đã ký bị bị tràn (tiềm năng); unsigned số học * không thể * tràn (kể từ khi thực hiện modulo 2^N). – Jens
Trường hợp 2 không đúng ... do tràn như trường hợp 1 – LPs
@LPs - đầu ra của trường hợp 2 có vẻ đúng mặc dù. Đó là câu hỏi của tôi, tràn dường như không xảy ra trong trường hợp này – artm