2017-09-23 49 views
44

只見代碼here下面一行中C.「int mask =〜0;」的用途是什麼?

int mask = ~0; 

我已打印的mask在C和C++的值。它始終打印-1

所以我有一些問題:

  • 爲什麼到面具變量分配值~0
  • ~0的用途是什麼?
  • 我們可以用-1代替~0嗎?
+38

「2」中的「〜0」只等於「-1」 –

+0

您能說明如何使用蒙版嗎?否則,我們只能猜測。 –

+1

@PaulFloyd:鏈接的源代碼是一個純粹的小動作練習...與提升權重一樣有用 – 6502

回答

78

這是一種便攜的方法,可以將整數中的所有二進制位設置爲1位,而無需知道當前體系結構中有多少位是整數。

+7

「-1」也將整數中的所有位設置爲1,而不知道「int」類型的寬度。這只是暗示使用兩個補碼 –

+25

@LưuVĩnhPhúc正確。 〜0方法具有較少的依賴性。適用於未簽名的,非二的讚美系統,並且(可以說)不那麼神祕。 –

+0

'long n =〜0;'也可以,但'unsigned long u =〜0u'''可能不會。 – chqrlie

36

C和C++允許3種不同的符號整數格式:符號 - 量值,一的補碼和2的補碼

~0將產生全1位而不管系統使用的符號格式。因此,它更便於攜帶超過-1

而且~0表示意圖更加清晰:反轉所有的位值0,而-1將表明,減一的值是必要的,而不是它的二進制表示

+0

正文說可以假定2的補碼32位整數 – 6502

8

這在2的補平臺(即假設)爲您提供了-1,但寫作-1直接由規則(僅整數0..255,一元!~和二進制&^|+<<>>允許禁止)。

0

在所有計算機體系結構中有多種編碼方式。當使用2的補碼時,這將始終爲真:~0 == -1。另一方面,一些計算機使用1的補碼來編碼上面的例子不真實的負數,因爲~0 == -0。 Yup,1s的補碼有負的零,這就是爲什麼它不是很直觀。

所以您的問題

  • 了〜0被分配給掩蓋所以在掩碼中的所有位均等於零1 - >製作mask & sth == sth
  • 了〜0是用來做等於1的所有位不管使你的代碼 - 使用
  • 你可以用-1來代替,如果你確信你的電腦平臺使用2的補數編碼

我個人的想法〜0的平臺儘可能多地與平臺無關。代碼成本相對較低,代碼變得無法證實

+0

只有當1s補碼實現支持負零時。另請參閱[此答案](https://stackoverflow.com/a/46387882/6717178) – JHBonarius

5

您正在研究一個編碼挑戰,對操作符和語言構造進行一系列限制以執行給定的任務。

第一個問題是返回值-1而不使用-運算符。

在代表與補負數的機器,價值-1爲代表,設定爲1所有位,所以~0計算爲-1

/* 
* minusOne - return a value of -1 
* Legal ops: ! ~ &^| + << >> 
* Max ops: 2 
* Rating: 1 
*/ 
int minusOne(void) { 
    // ~0 = 111...111 = -1 
    return ~0; 
} 

文件中的其他問題並不總是正確實施。第二個問題,返回表示所述事實的一個int值將適合於一個16位有符號short一個布爾值有一個缺陷:

/* 
* fitsShort - return 1 if x can be represented as a 
* 16-bit, two's complement integer. 
* Examples: fitsShort(33000) = 0, fitsShort(-32768) = 1 
* Legal ops: ! ~ &^| + << >> 
* Max ops: 8 
* Rating: 1 
*/ 
int fitsShort(int x) { 
    /* 
    * after left shift 16 and right shift 16, the left 16 of x is 00000..00 or 111...1111 
    * so after shift, if x remains the same, then it means that x can be represent as 16-bit 
    */ 
    return !(((x << 16) >> 16)^x); 
} 

左移負值或一個數字,其偏移值超出範圍int有未定義的行爲,右移一個負值是實現定義的,所以上述解決方案是不正確的(儘管它可能是預期的解決方案)。

3

Loooong之前,這是您如何在非常有限的設備(如1K ZX 80或ZX 81計算機)上節省內存。在BASIC,你會

Let X = NOT PI 

而非

LET X = 0 

由於數字被存儲爲4字節浮點,後者需要比所述第一NOT PI替代方案中,其中每個的NOT和PI 2字節更佔用一個字節。

+0

不完全。在這些例子中,所有(關鍵)字都是由單個字節編碼的,以及等號,變量名和_visible_零本身。但是,數字常量後跟(轉義字節?)加上4字節的浮點值,該值由執行程序使用,但未在源中顯示。因此,這裏的大小差異是3甚至4字節,而不是2. – CiaPan

+0

我應該工作......只是在某些ZX Spectrum仿真器上做了這件事,並將其保存到磁帶/磁盤。第一個使用40和第35個字節,因此有5個字節的差異。那麼,如果你只有ZX 81上的1k,那麼我認爲這在文件大小上節省了一半的百分比,這就是它被使用的原因......回到OP問題 - 你能夠保存一個或兩個字節(或5)今天通過使用說x =〜0而不是x = -1?也許使用諸如long x =〜0之類的轉換? – skaak

+0

我真的應該工作......只是在幾個簡單的方法嘗試這在c中,但編譯的文件是-1,〜0和〜(0x00)相同的大小......我相信有一些體系結構將節省大約一個字節,但是現在當然必須不惜一切代價來避免這樣的怪異。編譯的文件大約爲8.5k字節。這會給可憐的ZX81一個心臟病發作...... – skaak