C语言中Int和Long的取值范围在32位到64位之间。

45

我对C语言中Int类型变量的取值范围感到困惑。

我知道32位无符号整型的取值范围为:0到65,535。 而32位有符号整型为-2,147,483,648到2,147,483,647。 这在32位机器上是可以的。但现在在64位机器上所有的东西是否都保持不变呢? 或者我的int容量不同了吗?

作为一个新手,我真的很困惑。 方法签名也没有帮助:)

unsigned long long int atomicAdd(unsigned long long int* address, unsigned long long int val);

8
32位无符号整数的最大值为2^32 - 1,远大于65535(2^16 - 1)。 - Will A
10个回答

70

在 C 和 C++ 中,您有这些最低要求 (即实际实现可能具有更大的数量级)

signed char: -2^07+1 to +2^07-1
short:       -2^15+1 to +2^15-1
int:         -2^15+1 to +2^15-1
long:        -2^31+1 to +2^31-1
long long:   -2^63+1 to +2^63-1

现在,在特定的实现中,您可以有各种位范围。 维基百科文章 很好地描述了这一点。


1
很好,你能说一下在问题的方法签名中long long int的定义吗? - Custodio
3
@Custodio你使用了unsigned long long,这意味着你至少拥有一个范围为0 .. 2^64-1的数值。 - Johannes Schaub - litb
3
抱歉长时间未评论,但我有一种感觉,即C语言遵循二进制补码算术,在N位数据类型中取值范围为[-2^(N-1), 2^(N-1)-1]。请问您能否验证一下(下端点没有额外的1)? - mg007
1
@krishna222,这并没有错。限制条件的起草不仅可以使用二进制补码,还可以使用一进制补码和符号大小。因此,最小下限是-2^31+1而不是-2^31(对于32位符号大小,结果将为-0)。 - Johannes Schaub - litb
@JohannesSchaub-litb,但是C、C++遵循二进制补码,对吧?int x = 0x80000000; printf("x = %d", x); -> 输出 x = -2147483648,这等于-2^31。 - sumanth232
显示剩余3条评论

20

C语言中,int并没有定义成32位。实际上,intlong都没有被定义成特定的大小。程序语言只保证sizeof(char)< = sizeof(short) < = sizeof(long)

从理论上讲,编译器可以将shortcharlong都定义成同样数量的位数。我知道有一些编译器实际上就是这样做了,除了char以外的所有类型都是如此。

这就是为什么C现在定义了像uint16_tuint32_t这样的类型,如果需要特定的大小,就应该使用其中之一。


5
这就是为什么我在我的Linux系统(GCC)上得到sizeof(int)=4和sizeof(long)=4的原因。因为没有特定的大小,只有一个最小尺寸。 - CᴴᴀZ
它还保证了一些最小尺寸。 - Martin Bonner supports Monica
1
@einpoklum - 我来重新表述一下,因为“OK”似乎让人们很烦恼。但我认为很多人认为某些东西是“标准”的,实际上并不是。他们制定这些大小类型(包括int8_t和uint8_t)的原因是有道理的。我非常确定它们确实可以合法地都是相同的大小。 - T.E.D.
@einpoklum 在 ISO C 中并不保证存在 int8_t。所有 intNN_t 类型都是可选的,如果实现不能满足要求,那么它将不提供这些类型。 - M.M
@chux - 我想这可能在无符号和有符号类型大小不同的平台上是一个有用的澄清。是否有这样的平台? - T.E.D.
显示剩余6条评论

19

K&R摘录:

short通常是16位,long是32位,int则为16位或32位。每个编译器可以自由选择适合自己硬件的大小,只需遵守以下限制: shortint至少为16位,long至少为32位,short不能超过intint不能超过long


您可以利用limits.h,其中包含十进制/浮点类型限制的定义:

#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include <float.h>


int main(int argc, char** argv) {

    printf("CHAR_BIT    :   %d\n", CHAR_BIT);
    printf("CHAR_MAX    :   %d\n", CHAR_MAX);
    printf("CHAR_MIN    :   %d\n", CHAR_MIN);
    printf("INT_MAX     :   %d\n", INT_MAX);
    printf("INT_MIN     :   %d\n", INT_MIN);
    printf("LONG_MAX    :   %ld\n", (long) LONG_MAX);
    printf("LONG_MIN    :   %ld\n", (long) LONG_MIN);
    printf("SCHAR_MAX   :   %d\n", SCHAR_MAX);
    printf("SCHAR_MIN   :   %d\n", SCHAR_MIN);
    printf("SHRT_MAX    :   %d\n", SHRT_MAX);
    printf("SHRT_MIN    :   %d\n", SHRT_MIN);
    printf("UCHAR_MAX   :   %d\n", UCHAR_MAX);
    printf("UINT_MAX    :   %u\n", (unsigned int) UINT_MAX);
    printf("ULONG_MAX   :   %lu\n", (unsigned long) ULONG_MAX);
    printf("USHRT_MAX   :   %d\n", (unsigned short) USHRT_MAX);
    printf("FLT_MAX     :   %g\n", (float) FLT_MAX);
    printf("FLT_MIN     :   %g\n", (float) FLT_MIN);
    printf("-FLT_MAX    :   %g\n", (float) -FLT_MAX);
    printf("-FLT_MIN    :   %g\n", (float) -FLT_MIN);
    printf("DBL_MAX     :   %g\n", (double) DBL_MAX);
    printf("DBL_MIN     :   %g\n", (double) DBL_MIN);
    printf("-DBL_MAX     :  %g\n", (double) -DBL_MAX);

    return (EXIT_SUCCESS);
}

也许你需要在你的机器上做一些微调,但这是一个很好的模板,可以开始了解(实现定义的)最小值和最大值。


K&R 的摘录不错!再加上一分,因为你的外套很漂亮!等等,我说外套了吗?好吧,你理解对了! - Sнаđошƒаӽ
1
@Elyasin,我该如何找到80位长双精度浮点数的极限?有什么建议吗? - Sagar
我没有列出来,但是如果定义了的话,你也应该在float.h文件中找到它。 - Ely
整数类型的强制转换在最好的情况下是多余的(C11 5.2.4.2.1/1) - M.M

9

没有一个确定的答案。标准定义了最小范围。int类型必须至少能够存储65535个数字。然而,大多数现代编译器允许int类型为32位值。另外,没有防止多种类型具有相同的容量(例如int和long)。

话虽如此,标准确实在你的特定情况下指出:

0 → +18446744073709551615

作为无符号长整型的范围。
进一步阅读:http://en.wikipedia.org/wiki/C_variable_types_and_declarations#Size

一个 int 必须至少能够容纳 32767。它可能无法容纳 65535。在典型的 16 位实现中,它将无法容纳。 - M.M

2
事实上,在大多数现代处理器(ARM、Intel/AMD、Alpha、SPARC、Itanium、PowerPC)上,无符号整数的范围将为0到2^32-1,即4,294,967,295 = 0xffffffff,因为int(包括有符号和无符号的)长度为32位,最大值如上所述。
(无符号短整型的最大值将为2^16-1=65,535)
(无符号长长整型的长度为64位(在大多数64位Linux系统下,long int已经足够了,但标准承诺提供64位的long long int),因此它们的范围为0到2^64-1=18446744073709551615)

2

在 C 和 C++ 中,一些变量的内存需求如下:

signed char: -2^07 至 +2^07-1
short: -2^15 至 +2^15-1
int: -2^15 至 +2^15-1
long: -2^31 至 +2^31-1
long long: -2^63 至 +2^63-1

signed char: -2^07 至 +2^07-1
short: -2^15 至 +2^15-1
int: -2^31 至 +2^31-1
long: -2^31 至 +2^31-1
long long: -2^63 至 +2^63-1

具体要求取决于编译器和硬件架构。

C 语言的国际标准只要求 short 变量的大小小于或等于 int 类型的大小,而 int 类型的大小又小于或等于 long 类型的大小。


4
这些数值是错误的。Johannes Schaub回答中给出的数值,正是标准规定实现需要支持的最低数值,你试图进行纠正的数值也是如此。 - interjay
具体来说,signed char 不需要支持 -2^7 (-128)。它只需要处理 -127。二进制补码机器将支持 -128,但是符号-幅度表示法只能到 -127(这正是限制为什么是这样的原因)。其他类型也是如此。 - Martin Bonner supports Monica

1

看一下limits.h。你可以找到你的编译器的具体值。INT_MIN和INT_MAX会很有用。


1

请查看您系统中的limits.h文件,它将告诉您系统特定的限制。或者检查man limits.h并转到“数值限制”部分。


0
一个32位的无符号整数的范围是从0到4,294,967,295。 0到65535将是一个16位的无符号整数。
一个无符号长长整型(在64位实现上,可能也包括ulong和可能是uint)的范围(至少)为0到18,446,744,073,709,551,615(2^64-1)。 理论上它可以更大,但至少目前很少甚至不存在。

-5

最好包含 stdlib.h。因为没有 stdlibg,它会花费很长时间。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接