回答
如果您使用的是C99編譯器,請將其轉換爲(unsigned long long)
。 你也可以(也應該)的結構擴展到8首或16個字節(這是作爲一個練習)
#include <limits.h>
#define BYTES_REQUIRED(i) \
!((unsigned long)(i) >> CHAR_BIT) ? 1 \
: !((unsigned long)(i) >> 2 * CHAR_BIT) ? 2 \
: !((unsigned long)(i) >> 3 * CHAR_BIT) ? 3 \
: 4
爲什麼我需要將它轉換爲無符號long long如果它是c99編譯器? –
由於'unsigned long long'不被C89識別,並且至少與'unsigned long'一樣大。使用'unsigned long long'不會丟失任何東西(除了C89兼容性)並且可能獲得更大範圍的工作值。 – pmg
它使用一個有效的分而治之的方法:如果你不
#define BYTES_REQUIRED(i) (((i) & 0xFFFF0000) ? (((i) & 0xFF000000) ? 4 : 3) : (((i) & 0xFF00) ? 2 : 1))
介意消除3個字節奇數的情況下,它有與其匹配任何原始類型,這樣做:
#define BYTES_REQUIRED(i) (((i) & 0xFFFF0000) ? 4 : (((i) & 0xFF00) ? 2 : 1))
被警告這些手柄沒有一個負數,因爲它看到的S ign作爲已用空間擴展了1位。這需要另一個條件來解釋(例如,如果是負的,否定的)。
您實際上需要計算log2(i)。對於編譯器和宏所支持的最大整數值,並沒有簡單的方法來做到這一點。
選項:
1.Calculate在一個循環中的對數:
// 64+-bit version:
unsigned long BYTES_REQUIRED(unsigned long long i)
{
unsigned long bits = 0;
while (i)
{
i >>= 1;
bits++;
}
if (bits == 0) bits = 1;
return (bits + 7)/8; // we're assuming that byte=8 bits, but CHAR_BIT may be > 8
}
2.使用編譯器的固有功能(有效地,專用CPU指令),如果有的話。對於MSVC++:
// 64-bit version, not available for 32-bit code:
unsigned long BYTES_REQUIRED(unsigned long long i)
{
unsigned long index;
if (_BitScanReverse64(&index, i) == 0)
{
index = 1;
}
return (index + 8)/8;
}
// 32-bit version, available for 32 and 64-bit code:
unsigned long BYTES_REQUIRED(unsigned long i)
{
unsigned long index;
if (_BitScanReverse(&index, i) == 0)
{
index = 1;
}
return (index + 8)/8;
}
// 64-bit version available for 32 and 64-bit code:
unsigned long BYTES_REQUIRED(unsigned long long i)
{
unsigned long index;
if (_BitScanReverse(&index, (unsigned long)(i >> 32)))
{
index += 32;
}
else if (_BitScanReverse(&index, (unsigned long)i) == 0)
{
index = 1;
}
return (index + 8)/8;
}
3.使用if
或?:
知道最大支持整數類型的大小...其他人已經描述了這種方法。
解決log-base-2給出的位的準確性,這是不需要的。你正在解決一個更難的問題,然後他問,然後分開額外的精度。 _BitScanReverse可能有些意義,因爲它在某些處理器上速度很快,但他要求在編譯時解決某些問題,所以無論如何性能無關緊要。內在原則使得代碼更加便於攜帶並且無需交換。 – VoidStar
不幸的是,你問了一個C宏,因爲這個C++模板化函數可能有幫助(它應該適用於你的編譯器支持的任何整數類型)。
template <typename T> int bytesRequired(T value) {
boost::function_requires< boost::IntegerConcept<T> >();
for (int i=0; i<=sizeof(T); i++, value/=256)
if (value == 0) return i;
}
另一種做法,應該是更快的(因爲它的網點),如果你不只是需要編譯時的評價,是由亞歷克斯提到的bitscan。
- 1. 在Python中存儲整數所需的字節數
- 2. 如何分割字符串以獲得所需的整數值?
- 3. 與數字相比,Pls_integer值需要「少」存儲。如何驗證?
- 4. 如何確定表示給定整數所需的字節數?
- 5. 如何減少獲得此結果所需的查詢數
- 6. C宏 - 如何獲得一個整數值到字符串文字
- 7. 如何計算存儲N位所需的長整數(64位)?
- 8. 如何獲得本月的整數值?
- 9. 如何獲得由整數的一些數字組成的最大數字
- 10. 如何找出需要多少字節來存儲一個值(int)在C
- 11. 轉換字節數組的字節位和存儲在整數數組
- 12. 如何獲得整個git存儲庫
- 13. 從存儲過程中如何獲得最大的數
- 14. 如何獲得數組中數值最大的字符串?
- 15. 如何獲得計數的最大值
- 16. 一個字節被如何存儲在整數
- 17. 如何存儲多個字節數組
- 18. 如何獲得所需的字符串從整個
- 19. 如何獲得給定數組顯示的所需值?
- 20. 如何獲得sprinner值作爲整數
- 21. 如何從res/integers.xml獲得整數值?
- 22. Android將數據存儲到緩存需要多少時間?或者,存儲的最大數據量是多少?
- 23. 如何存儲整數字符串
- 24. 未存儲所需參數的數組
- 25. 如何將整數值存儲在wp7的獨立存儲中?
- 26. 將8字節值的每個字節存儲在數組中
- 27. 如何獲得其存儲在jquery.data所有數據()
- 28. 如何以最緊湊的方式存儲字節或值?
- 29. 整數除法,並獲得整數值
- 30. 如何獲得android微調值和存儲數據的意圖?
爲什麼一個宏?你知道如何使用正常的功能嗎? – Mat
@Mat,實際上我只能想到這個:'if(i <255)return 1;否則if(i> 255 && i <2^16)返回2; ...',這太長了是一個宏。 –
爲什麼你需要一個宏? – Mat