C中可存储10,000,000的最小数据类型是什么?

时间:2015-08-21 18:04:45

标签: c memory

我正在尝试使用C编写的简单控制台应用程序来庆祝StackOverflow上的10,000,000个问题,但我不想浪费任何内存。将数字10,000,000存储在内存中的最有效方法是什么?

8 个答案:

答案 0 :(得分:7)

您正在寻找的类型是来自int_least32_t的{​​{1}},它将为您提供至少32位的最小类型。这种类型保证存在于C99实现中。

确保stdint.h等确切宽度的类型设置不存在,但是如果没有它就很难找到平台。

答案 1 :(得分:3)

从技术上讲,24位整数可以存储它,但C中没有24位基元类型。您必须使用32位intlong

对于性能最好的方法,浪费1个未使用的内存字节是无关紧要的。

现在,如果出于学习目的,你真的真的想在最小的内存中存储1000万个,而你甚至愿意自己创建数据存储方法来实现它,你可以将它存储在1个字节中,自定义遵循float示例的存储方法。您只需要4位表示10,其他3位表示7,并且在1字节中需要计算pow(10, 7);所需的所有数据。它甚至会为您留下额外的空位,您可以将其用作标志。

答案 2 :(得分:3)

数字10000000(一千万)需要24位作为无符号值存储。

大多数C实现没有24位类型。任何符合1999 C标准或更高版本的实现都必须提供<stdint.h>标头,并且必须定义以下所有内容:

uint_least8_t
uint_least16_t
uint_least32_t
uint_least64_t

每个都是(别名)无符号整数类型,至少具有指定的宽度,因此没有更窄的整数类型至少具有指定的宽度。其中,uint_least32_t是保证保留值10000000的最窄类型。

在绝大多数C实现中,uint_least32_t是您正在寻找的类型 - 但在支持24位整数的实现上,将有一个更窄的类型满足您的要求。

这样的实现可能定义uint24_t,假设它是无符号的24位类型没有填充位。所以你可以这样做:

#include <stdint.h>

#ifdef UINT_24_MAX
typedef uint24_t my_type;
#else
typedef uint_least32_t my_type;
#endif

那仍然不是100%可靠(例如,如果有28位类型但没有24位类型,这将会错过它)。在最坏的情况下,它会选择uint_least32_t

如果您想限制自己使用预定义类型(可能是因为您希望支持C99之前的实现),您可以这样做:

#include <limits.h>

#define TEN_MILLION 10000000

#if UCHAR_MAX >= TEN_MILLION
typedef unsigned char my_type;
#elif USHRT_MAX >= TEN_MILLION
typedef unsigned short my_type;
#elif UINT_MAX >= TEN_MILLION
typedef unsigned int my_type;
#else
typedef unsigned long my_type;
#endif

如果您只想要保证在所有实现上保持值10000000的最窄预定义类型(即使某些实现可能具有更窄的类型,可以保留它),使用longint可以缩小为16位)。

如果您不需要使用整数类型,则可以简单地定义一个保证为3字节宽的类型:

typedef unsigned char my_type[3];

但实际上这比你需要CHAR_BIT > 8更宽:

typedef unsigned char my_type[24 / CHAR_BIT]

但如果24不是CHAR_BIT的倍数,则会失败。

最后,您的要求是代表数字10000000;您没有说您需要能够代表任何其他号码:

enum my_type { TEN_MILLION };

或者您可以定义1位位域,值1表示10000000,值0表示 10000000

答案 3 :(得分:1)

如果您想存储数字n&gt;在无符号整数数据类型中为0,则整数类型中至少需要⌈lg(n + 1)⌉位。在您的情况下,⌈lg(10,000,000 + 1)⌉= 24,因此您选择的数据类型至少需要24位。

据我所知,C规范不包含特定24位的整数类型。最接近的选择是使用uint32_t之类的东西,但是(如评论中所提到的)这种类型可能不存在于所有编译器中。类型int_least32_t保证存在,但可能比必要的大。

或者,如果您只需要它在一个特定系统上工作,那么您的特定编译器可能具有24位整数的编译器特定数据类型。 (剧透:它可能不会。^ _ ^)

答案 4 :(得分:1)

uint16_t中可存储的最大值为0xFFFF,小数为65535。这显然不够大。

uint32_t中可存储的最大值为0xFFFFFFFF,小数为4294967295。这显然足够大了。

您似乎需要使用uint32_t

答案 5 :(得分:1)

非智能答案是uint32_t或int32_t。

但如果你内存真的很低,

uint8_t millions_of__questions;

但是,只有你是定点算术的粉丝,并且愿意处理一些错误(或者正在使用一些专门的数字表示方案)。取决于您在存储它之后使用它做什么以及您希望在您的&#34;数据类型中存储的其他数字&#34;。

答案 6 :(得分:1)

struct {
   uint16_t low;  // Lower 16 bits
   uint8_t  high; // Upper 8 bits
} my_uint24_t;

这提供24位存储空间,可存储最多16,777,215的值。它不是本机类型,需要特殊的访问器功能,但在大多数平台上占用的空间比32位整数少(可能需要打包)。

答案 7 :(得分:0)

来自uint32_t

<stdint.h>可能是您的首选数据类型。由于uint16_t只能存储2 ^ 16-1 = 65535,因此下一个可用类型为uint32_t

请注意uint32_t存储无符号值;如果您还想存储已签名的号码,请使用int32_t。您可以在此处找到更多信息:http://pubs.opengroup.org/onlinepubs/009695399/basedefs/stdint.h.html