2017-09-23 52 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