何时使用不同的整数类型?

时间:2011-06-11 12:38:52

标签: math programming-languages types size

编程语言(例如c,c ++和java)通常有几种类型用于整数运算:

  • signedunsigned个类型
  • 不同尺寸的类型:shortintlonglong long
  • 保证和非保证(即依赖于实现)大小的类型:
    例如int32_t vs int(我知道int32_t不是该语言的一部分)

如何总结何时应该使用它们?

8 个答案:

答案 0 :(得分:9)

默认的整数类型(int)在几乎所有语言中都获得“等于第一”的优惠待遇。因此,如果不存在偏好其他类型的理由,我们可以将其用作默认值。

这样的原因可能是:

  • 如果您知道需要额外的范围,请使用较大的类型;如果您想节省内存并且不介意较小的范围,请使用较小的类型。
  • 如果您打算使用bit shifting运算符(<<>>),请使用无符号类型确保您的整数表示中没有任何“额外”1。
  • 如果语言不保证类型的最小(或甚至固定)大小(例如C / C ++ vs C#/ Java),并且您关心它的属性,您应该更喜欢某种生成具有保证大小的类型的机制(例如int32_t) - 如果你的程序是可移植的并且希望用不同的编译器编译,那么这就变得更加重要了。

更新(扩展保证尺寸类型)

我个人认为,没有保证固定大小的类型比现在更麻烦。我不会深入了解产生它们的历史原因(简要地说:源代码可移植性),但事实是,在2011年,很少有人(如果有的话)从中受益。

另一方面,使用这些类型时可能会出现许多问题:

  • 该类型证明没有必要的范围
  • 您可以访问变量的底层内存(可能是序列化它),但由于处理器的字节顺序和类型的非固定大小,最终会引入错误

由于这些原因(也可能还有其他原因),使用这些类型在理论上是一个主要的痛苦。此外,除非要求极端可移植性,否则您根本无法获益。事实上,像int32_t这样的typedef的整个目的是完全消除松散大小类型的使用。

实际上,如果您知道您的程序不会被移植到另一个编译器或体系结构,您可以忽略这些类型没有固定大小的事实,并将它们视为编译器的已知大小用于他们。

答案 1 :(得分:6)

逐一问你的问题:

  1. signedunsigned:取决于您的需求。如果您确定,该号码将是未签名的 - 请使用unsigned。这将使您有机会使用更大的数字。例如,signed char(1B)具有范围 [ - 128:127] ,但如果它是unsigned - 最大值加倍(你有一个以上位以使用 - sign bit,因此unsigned char可能 255 (所有位均为1)

  2. shortintlonglong long - 这些都很清楚,不是吗?最小的整数(char除外)是short,下一个是int,等等。但这些是平台相关的 - int可能是2B(很久很久以前:D ),4B(通常)。 long可以是4B(在32位平台中),或8B(在64位平台上),等等。long long不是C ++中的标准类型(它将在C ++ 0x中),但通常它是一个int64_t的typedef。

  3. int32_t vs int - int32_t以及其他此类类型可确保其尺寸。例如,int32_t保证为32位,而正如我已经说过的,int的大小取决于平台。

答案 2 :(得分:4)

使用short来节省内存,使用更长时间来表示更大的数字。如果您没有这样的要求,请考虑您将与哪些API共享数据并自行设置,这样您就不必投射或转换太多。

答案 3 :(得分:2)

通常,您应该使用符合程序要求的类型,并尽可能提高可读性和未来的可维护性。

话虽如此,正如克里斯指出的那样,人们确实使用短裤和英特来节省记忆。考虑以下情况,您有1,000,000(相当小的数量)整数(通常为32字节)与短路(通常为16字节)。如果你知道你永远不需要代表一个大于32,767的数字,你可以用一个短数字。或者你可以使用unsigned short,如果你知道你永远不需要代表一个大于65,535的数字。这样可以节省:((32 - 16)x 1,000,000)= 16k的内存。

答案 4 :(得分:1)

你还应该考虑使用无界的整数和自然,因为你想要正确地建模数字而不必担心溢出。

GMP和OpenSSL等库提供了支持任意大结果的“大号” - 这通常是最安全的,除非你能证明你的计算结果在界限范围内。

此外,许多语言默认为无界整数类型,因为它们更安全。

答案 5 :(得分:1)

对不同大小整数类型的需求源于两个基本问题:类型大小几乎需要在较低级别上知道,并且在过去的内存限制中,它在每天的使用中都很重要,因为你几乎没有玩。如果你正在进行基本算术,那么你使用哪种类型几乎是不重要的。例如,当从1到100循环时,如果您的类型适合并且如果您需要/不使用正确的类型,则使用uint16_tuint64_t并不重要需要签字。

但是,当您想要扩展/需要优化时,它变得很重要。如果你想分配1,000,000,000个这样的整数,那么说“每个将是64位以防万一”或“我将使用内置类型”不会削减它 - 这是8,000,000,000字节,大约7.5GB数据的。现在10亿个64位整数听起来不太可行,但这些整数可能是3D数组中的点(1000 ^ 3),在这种情况下,你也可以获得内容的指针大小。例如,对于您的值,您可以进一步使用8位整数。您可以分配多少通知您的算法 - 如果您不能一次分配那么多数据,您可能会考虑mmap或一次处理部分数据(a.k.a.处理自己交换)。如果您不需要特定大小的值,那么当您开始使用更多约束类型时。同样,使用无符号类型可以获得2的额外幂。非常有用。

如果您正在编写程序集以与C / C ++一起使用,那么了解数据类型的大小就非常重要,特别是在分配本地堆栈空间或从内存地址读取变量时(相反)已经在登记册中)。将其视为完全使用void*进行编程。因此,我倾向于习惯使用stdint.h定义的类型,以便在混合两者时我总是知道我的大小和格式。

答案 6 :(得分:1)

通常,您使用int,除非您需要扩展它,因为您需要更大的范围或者您想要缩小它,因为您知道该值仅在较小范围内有意义。由于记忆考虑,你需要改变是非常罕见的 - 它们之间的区别微乎其微。

答案 7 :(得分:1)

也许只是为了好玩,这里有一个简单的例子,说明你根据选择的类型,你有一个结果或另一个。

当然,在我看来,您选择一种或另一种的实际原因与其他因素有关。例如,伟大的shift operator

#include <iostream>
#include <cmath>
using namespace std;

int main()
{
    int i;

    //unsigned long long x;
    //int x;
    short x;

    x = 2;
    for (i=2; i<15; ++i)
    {
        x=pow(x,2);
        cout << x << endl;
    }
    return 0;
}