2010-05-14 81 views
19

我讀了整數常量的Microsoft特定後綴「i64」。我想做一個UNSIGN的轉變成ULONGLONG。
ULONGLONG bigNum64 = 0x800000000000000i64 >> myval;如何在VS2008中指定一個64位的unsigned int const 0x8000000000000000?

在正常的C中,我會使用後綴「U」,例如,類似的32位操作將是
ULONG bigNum32 = 0x80000000U >> myval;

我不希望2的補碼符號擴展傳播高位。我想要一個64位常數的UNSIGNED移位。我認爲我的第一個聲明是要做一個正確的轉變。

我試過0x800000000000000i64U0x800000000000000u64但有編譯器錯誤。

+2

在我的Visual Studio中,limits.h具有語法0xffffffffffffffffui64,因此0x800000000000000ui64應該可以工作。但是,這是一個較新的版本,所以也許它在Visual Studio 2008中不起作用。 – anatolyg 2015-07-21 10:19:03

+1

對於十六進制整數,@MM:U可以是unsigned int,unsigned long int或unsigned long long int不變。 UL可以是'unsigned long int'或'unsigned long long int'。參見C標準的6.4.4.1(或C++標準的2.14.3)。鑑於此,我不認爲OP的例子不正確或需要修改。 – Cornstalks 2016-03-23 00:01:59

+0

這是一個較老的問題。在C++ 11中,我認爲不需要任何後綴。只有一個無符號的64位整型可以保存該常量。無符號long long必須至少爲64位,並且這是編譯器應該嘗試以十六進制格式的文本類型的列表。 http://en.cppreference.com/w/cpp/language/integer_literal – 2016-03-23 17:24:08

回答

29

可以使用後綴ull這是標準(C99和C++ 0x)方式來指定unsigned long long整數文字,並且long long至少爲64位。

+0

這工作!謝謝! – franji1 2010-05-14 16:22:21

+0

**編譯器警告**''-Wlong-long'可以在編譯器命令行或'#pragma GCC診斷忽略'-Wlong-long''的代碼中禁用。 [這裏是一個很好的例子](http://stackoverflow.com/a/16062548/673991)暫時爲一段代碼做這件事。 – 2014-06-20 13:31:12

+0

@ BobStein-VisiBone:如果您使用C99模式或更高版本進行編譯,您將不會收到任何有關「long long」的警告。 – AnT 2016-03-23 14:46:19

0

這裏有一個辦法:

int main() 
{ 
    uint64_t val1=0x1p63; //1 * 2**63 
    uint64_t val2=((uint64_t)0x1p63)-1; //0x1p63 is a float constant 
    uint64_t val3= ((uint64_t)0x1p63) >> 2; 
    cout << hex << "val1=" << val1 << " val2=" << val2 << " val3=" << val3 << endl; 
    return 0; 
} 

VAL1 = 80000000億VAL2 = 7fffffffffffffff VAL3 = 20000000億

5

滑稽足夠了,但你實際上並不需要任何後綴添加到您的十六進制常量,以便它被正確處理。 C標準和C++標準的第2.14.3第6.4.4.1包含下表:

Suffix  | Decimal Constant  | Octal or Hexadecimal Constant 
-------------+------------------------+------------------------------ 
none   | int     | int 
      | long int    | unsigned int 
      | long long int   | long int 
      |      | unsigned long int 
      |      | long long int 
      |      | unsigned long long int 
-------------+------------------------+------------------------------ 
u or U  | unsigned int   | unsigned int 
      | unsigned long int  | unsigned long int 
      | unsigned long long int | unsigned long long int 
-------------+------------------------+------------------------------ 
l or L  | long int    | long int 
      | long long int   | unsigned long int 
      |      | long long int 
      |      | unsigned long long int 
-------------+------------------------+------------------------------ 
Both u or U | unsigned long int  | unsigned long int 
and l or L | unsigned long long int | unsigned long long int 
-------------+------------------------+------------------------------ 
ll or LL  | long long int   | long long int 
      |      | unsigned long long int 
-------------+------------------------+------------------------------ 
Both u or U | unsigned long long int | unsigned long long int 
and ll or LL |      | 

此表告訴我們一個整型常量會產生什麼樣的類型。整數常量的類型將是它適合的第一個類型。

這意味着編譯器將遍歷以下類型的十六進制常量0x800000000000000(它沒有後綴,所以它使用「none」行,它是一個十六進制常量,因此它使用「十六進制常量」列),它會使用能夠存儲值*第一種類型:

  1. int:沒有,一個32位帶符號整數不能存儲此值。
  2. unsigned int:不,一個32位無符號整數不能存儲這個值。
  3. long int:不,32位有符號整數不能存儲此值。
  4. unsigned long int:不,32位無符號整數不能存儲此值。
  5. long long int:否,64位有符號整數不能存儲此值。
  6. unsigned long long int,一個64位無符號整數可以存儲此值。由於這是第一種可以完全存儲該值的類型,因此這是整型常量將具有的類型。

因此,要回答你的問題「我如何編寫和使用的價值0x800000000000000並確保編譯器將不能治療高位爲符號位?」:簡單地只寫unsigned long long value = 0x800000000000000

如果您想對值進行一些按位運算,您可以繼續前進並執行該操作(即只寫0x800000000000000 >> myval)。您可以保證它不會被視爲溢出的有符號整數,並且您的右移不會執行任何符號擴展,因爲它是正值。

*我假設int是32位,long是32位,並且是long long 64比特。請注意,您的編譯器可能會爲這些類型使用不同的位大小,這可能會改變最終結果(儘管過程仍然相同)。

+0

你需要小心,雖然。如果你想聲明一個沒有後綴的無符號long long,那麼你會遇到麻煩:考慮'printf(「%lx \ n」,(0x40000000 <<1)>> 1);'左/右移應該返回0x40000000,但如果你運行這個,你會得到0xc0000000。 – 2016-07-26 00:28:10

相關問題