簡體   English   中英

C中可存儲10,000,000的最小數據類型是什么?

[英]What's the smallest data type in C that can store the number 10,000,000?

我試圖通過一個用C編寫的簡單控制台應用程序來慶祝StackOverflow上的10,000,000個問題,但我不想浪費任何內存。 在內存中存儲數字10,000,000的最有效方法是什么?

您正在尋找的類型是來自stdint.h int_least32_t ,它將為您提供至少32位的最小類型。 這種類型保證存在於C99實現中。

不保證存在精確寬度的typedef,例如int32_t ,盡管你很難找到沒有它的平台。

從技術上講,24位整數可以存儲,但C中沒有24位基元類型。您必須使用32位intlong

對於性能最好的方法,浪費1個未使用的內存字節是無關緊要的。

現在,如果出於學習目的,你真的想在最小的內存中存儲1000萬,並且你甚至願意自己創建數據存儲方法來實現它,你可以通過自定義存儲來存儲1個字節以float為例的方法。 您只需要4位表示10,其他3位表示7,並且在1字節中需要計算pow(10, 7);所需的所有數據pow(10, 7); 它甚至可以為您提供額外的免費位,您可以將其用作標志。

數字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

如果要在無符號整數數據類型中存儲數字n> 0,則整數類型中至少需要⌈lg(n + 1)⌉位。 在你的情況下,⌈lg(10,000,000 + 1)⌉= 24,所以你選擇的數據類型至少需要24位。

據我所知,C規范不包含特定24位的整數類型。 最接近的選擇是使用像uint32_t這樣的東西,但是(如評論中所提到的)這種類型可能不存在於所有編譯器上。 int_least32_t類型保證存在,但可能比必要的大。

或者,如果您只需要它在一個特定系統上工作,您的特定編譯器可能具有24位整數的編譯器特定數據類型。 (劇透:它可能沒有。^ _ ^)

可以存儲在uint16_t中的uint16_t0xFFFF ,十進制為65535 這顯然不夠大。

可以存儲在uint32_t中的uint32_t0xFFFFFFFF ,即十進制的4294967295 這顯然足夠大了。

看起來你需要使用uint32_t

非智能答案是uint32_t或int32_t。

但如果你內存真的很低,

uint8_t millions_of__questions;

但是,只有你是定點算術的粉絲,並願意處理一些錯誤(或使用一些專門的數字表示方案)。 取決於您在存儲它之后使用它做什么以及您希望在“數據類型”中存儲的其他數字。

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

這提供24位存儲,可存儲高達16,777,215的值。 它不是本機類型,需要特殊的訪問器功能,但在大多數平台上占用的空間比32位整數少(可能需要打包)。

來自<stdint.h> 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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM