C语言中如何确定无符号长整型的范围?
How can I confirm the range of unsigned long integer in C?
unsigned long 在我的 Linux gcc 上有 8 个字节。
unsigned long long 在我的 Linux gcc 上也有 8 个字节。
所以我认为他们可以显示的整数范围是从 0 min 到 (2^64 - 1)max.
现在我想确认一下我是不是正确的。
这是我的代码:
#include <stdio.h>
int main(void)
{
printf("long takes up %d bytes:\n", sizeof(long));
printf("long long takes up %d bytes:\n", sizeof(long long));
unsigned long a = 18446744073709551615;
a++;
printf("a + 1 = %lu\n", a);
unsigned long long b = 18446744073709551615;
b++;
printf("b + 1 = %llu\n", b);
return 0;
}
但是,代码无法编译,我收到以下警告:
warning: integer constant is so large that it is unsigned
我哪里做错了?我该如何修改代码?
用-1初始化无符号数。这将自动成为 C 中的最大值。
#include <stdio.h>
int main(void)
{
printf("long takes up %d bytes:\n", sizeof(long));
printf("long long takes up %d bytes:\n", sizeof(long long));
unsigned long a = -1;
printf("a = %lu\n", a);
unsigned long long b = -1;
printf("b = %llu\n", b);
return 0;
}
更新:根据评论更改了代码:)
您在 <limits.h>
中找到了一些有用的定义。
初始化num时,可以为unsigned long
追加"UL",为[=追加ULL 12=]。
例如:
unsigned long a = 18446744073709551615UL;
unsigned long long b = 18446744073709551615ULL;
此外,使用 %zu
而不是 %d
因为 sizeof return size_t
.
根据cppreference:
- integer-suffix, if provided, may contain one or both of the following (if both are provided, they may appear in any order:
unsigned-suffix
(the character u
or the character U
)
long-suffix
(the
character l
or the character L
) or the long-long-suffix
(the character
sequence ll
or the character sequence LL
) (since C99)
C standard 5.2.4.2.1 整数类型的大小 <limits.h>
:
1 The values given below shall be replaced by constant expressions suitable for use in #if preprocessing directives. Moreover, except for
CHAR_BIT
and MB_LEN_MAX
, the following shall be replaced by
expressions that have the same type as would an expression that is an
object of the corresponding type converted according to the integer
promotions. Their implementation-defined values shall be equal or
greater in magnitude (absolute value) to those shown, with the same
sign.
如 rsp 所述,您可以使用 UL
和 ULL
指定文字的类型。
但这不会在您的算术代码中得出结论性的结果。
您打印的价值将始终是 0
因为
2^64 % 64 = 0 // 64 = 8 byte
2^64 % 32 = 0 // 32 = 4 byte
2^64 % 16 = 0 // 16 = 2 byte
如您所见,变量大小总是加倍,因此,如果您使用 8 字节的包装数字,它只是将多种类型包装在较小的尺寸上,并产生相同的结果。
sizeof
会显示正确的值。
但通常您希望在代码中而不是在输出中检查这些内容,因此您可以按照 Arndt Jonasson 的建议使用 limits.h
。
或者你可以使用static_assert
在编译时检查。
How can I confirm the range of unsigned long integer in C?
最佳,只需使用 <limits.h>
中的宏即可。它更好地自我记录代码的意图。
unsigned long long b_max = ULLONG_MAX;
或者,将 -1 分配给 unsigned 类型。由于 -1 不在 unsigned 类型的范围内,它将通过将该类型的 MAX 值加 1 来转换为目标类型。即使在具有填充。
... if the new type is unsigned, the value is converted by repeatedly adding or subtracting one more than the maximum value that can be represented in the new type until the value is in the range of the new type. C11dr §6.3.1.3 2
对于 unsigned 类型,最小值当然是 0。
unsigned long long b_min = 0;
unsigned long long b_max = -1;
printf("unsigned long long range [%llu %llu]\n", b_min, b_max);
请注意,挑剔的编译器会抱怨使用 b_max = -1;
分配超出范围的值。使用 ULLONG_MAX
。
Where did I do wrong?
警告 "warning: integer constant is so large that it is unsigned" 是由于 18446744073709551615
是您平台上 long long
范围之外的整数十进制常量。朴素的十进制常量仅限于此。追加 U
或 u
。那么编译器会考虑unsigned long long
.
unsigned long long b = 18446744073709551615u;
此外,没有 C 规范说 18446744073709551615 是 unsigned long long
的最大值。它必须至少 。它可能更大。所以分配 b = 18446744073709551615u
可能不会分配 max 值。
How can I modify the code ?
如上所示
unsigned long 在我的 Linux gcc 上有 8 个字节。
unsigned long long 在我的 Linux gcc 上也有 8 个字节。
所以我认为他们可以显示的整数范围是从 0 min 到 (2^64 - 1)max.
现在我想确认一下我是不是正确的。
这是我的代码:
#include <stdio.h>
int main(void)
{
printf("long takes up %d bytes:\n", sizeof(long));
printf("long long takes up %d bytes:\n", sizeof(long long));
unsigned long a = 18446744073709551615;
a++;
printf("a + 1 = %lu\n", a);
unsigned long long b = 18446744073709551615;
b++;
printf("b + 1 = %llu\n", b);
return 0;
}
但是,代码无法编译,我收到以下警告:
warning: integer constant is so large that it is unsigned
我哪里做错了?我该如何修改代码?
用-1初始化无符号数。这将自动成为 C 中的最大值。
#include <stdio.h>
int main(void)
{
printf("long takes up %d bytes:\n", sizeof(long));
printf("long long takes up %d bytes:\n", sizeof(long long));
unsigned long a = -1;
printf("a = %lu\n", a);
unsigned long long b = -1;
printf("b = %llu\n", b);
return 0;
}
更新:根据评论更改了代码:)
您在 <limits.h>
中找到了一些有用的定义。
初始化num时,可以为unsigned long
追加"UL",为[=追加ULL 12=]。
例如:
unsigned long a = 18446744073709551615UL;
unsigned long long b = 18446744073709551615ULL;
此外,使用 %zu
而不是 %d
因为 sizeof return size_t
.
根据cppreference:
- integer-suffix, if provided, may contain one or both of the following (if both are provided, they may appear in any order:
unsigned-suffix
(the characteru
or the characterU
)long-suffix
(the characterl
or the characterL
) or thelong-long-suffix
(the character sequencell
or the character sequenceLL
) (since C99)
C standard 5.2.4.2.1 整数类型的大小 <limits.h>
:
1 The values given below shall be replaced by constant expressions suitable for use in #if preprocessing directives. Moreover, except for
CHAR_BIT
andMB_LEN_MAX
, the following shall be replaced by expressions that have the same type as would an expression that is an object of the corresponding type converted according to the integer promotions. Their implementation-defined values shall be equal or greater in magnitude (absolute value) to those shown, with the same sign.
如 rsp 所述,您可以使用 UL
和 ULL
指定文字的类型。
但这不会在您的算术代码中得出结论性的结果。
您打印的价值将始终是 0
因为
2^64 % 64 = 0 // 64 = 8 byte
2^64 % 32 = 0 // 32 = 4 byte
2^64 % 16 = 0 // 16 = 2 byte
如您所见,变量大小总是加倍,因此,如果您使用 8 字节的包装数字,它只是将多种类型包装在较小的尺寸上,并产生相同的结果。
sizeof
会显示正确的值。
但通常您希望在代码中而不是在输出中检查这些内容,因此您可以按照 Arndt Jonasson 的建议使用 limits.h
。
或者你可以使用static_assert
在编译时检查。
How can I confirm the range of unsigned long integer in C?
最佳,只需使用 <limits.h>
中的宏即可。它更好地自我记录代码的意图。
unsigned long long b_max = ULLONG_MAX;
或者,将 -1 分配给 unsigned 类型。由于 -1 不在 unsigned 类型的范围内,它将通过将该类型的 MAX 值加 1 来转换为目标类型。即使在具有填充。
... if the new type is unsigned, the value is converted by repeatedly adding or subtracting one more than the maximum value that can be represented in the new type until the value is in the range of the new type. C11dr §6.3.1.3 2
对于 unsigned 类型,最小值当然是 0。
unsigned long long b_min = 0;
unsigned long long b_max = -1;
printf("unsigned long long range [%llu %llu]\n", b_min, b_max);
请注意,挑剔的编译器会抱怨使用 b_max = -1;
分配超出范围的值。使用 ULLONG_MAX
。
Where did I do wrong?
警告 "warning: integer constant is so large that it is unsigned" 是由于 18446744073709551615
是您平台上 long long
范围之外的整数十进制常量。朴素的十进制常量仅限于此。追加 U
或 u
。那么编译器会考虑unsigned long long
.
unsigned long long b = 18446744073709551615u;
此外,没有 C 规范说 18446744073709551615 是 unsigned long long
的最大值。它必须至少 。它可能更大。所以分配 b = 18446744073709551615u
可能不会分配 max 值。
How can I modify the code ?
如上所示