【问题标题】:~ operator in C~ C 中的运算符
【发布时间】:2013-10-29 00:30:14
【问题描述】:

这个程序的输出是-13。我从来没有完全理解 C 中的 ~ 运算符。为什么它给出 -13 作为输出?如何将 ~ 运算符限制为数字的 4 位?

    #include<stdio.h>
    #include<conio.h>
    int main()
    {
        int a = 12;
        a = ~a;
        printf("%d",a);
        getch();
        return;
    } 

【问题讨论】:

  • 阅读 C99 6.5.33,一元算术运算符。 “~ 运算符的结果是其(提升的)操作数的按位补码(即,当且仅当未设置转换操作数中的相应位时,结果中的每个位都被设置)。整数提升在"关于整数提升的部分会带你到C99 6.3.1.1,有点头晕,不过你问了。
  • 您得到 -13,因为系统使用二进制补码表示负数,而 ~ 运算符为您提供一个补码。二进制补码定义为一个补码加一。

标签: c operators


【解决方案1】:

要将效果限制在指定的位数,只需使用按位掩码,例如:

#include <stdio.h>

int main(void) {
    int a = 16;             /* 10000 in binary */
    int b = ~a;             /* Will interpret b as -17 in two's complement */
    int c = (a & ~0xF) | (~a & 0xF); /* Will limit operator to rightmost 4 bits,
                                        so 00000 becomes 01111, and c will become
                                        11111, not 11...101111, so c will be 31     */

    printf("a is %d, b is %d, c is %d\n", a, b, c);
    return 0;
}

输出:

paul@local:~/src/c/scratch$ ./comp
a is 16, b is -17, c is 31
paul@local:~/src/c/scratch$

【讨论】:

  • 你是如此亲密。但是,在执行 a | (~a &amp; 0xF) 之前,您需要清除最右边的四位。它对您有用的原因是,您将a 用作16,二进制是10000。使用a 作为17 运行你的程序,二进制是10001,你仍然会看到输出为31
【解决方案2】:

运算符 ~ 是 C 中的逻辑 not,即当应用于整数时,它会翻转其二进制表示中的每一个 it。请注意,将整数简单地定义为int 使其成为无符号整数。这意味着第一个它被用作符号位。由于否定定义为-a = ~a + 1,您可以看到~a = -a - 1。如果您只想翻转int 的最后 4 位(或更一般地说是最后 k)位,您可以这样做

int k = 4;
int mask = (1 << k) - 1;
int b = a ^ mask;

【讨论】:

    【解决方案3】:

    (12)10 二进制是(1100)2

    波浪号是按位补码运算符,它使1100 --> 0011。但是,如果您在 32 位平台上工作,实际上我们得到的是:

    0000 0000 0000 0000 0000 0000 0000 1100
    

    谁的位补是:

    1111 1111 1111 1111 1111 1111 1111 0011
    |
    

    现在因为最左边的位是符号,所以数字变为负数。如果您使用 unsigned int,您将能够更好地理解正在发生的事情:

    unsigned int a = 12;
    a = ~a;
    

    将给予:

    1111 1111 1111 1111 1111 1111 1111 0011
    

    4294967283

    【讨论】:

      【解决方案4】:

      ~ 运算符充当二进制 NOT,也就是说,它翻转数字中的所有位。有符号整数中的负数存储为two's complement

      【讨论】:

        【解决方案5】:

        这是一个按位运算符(一个的补码)以这种方式工作:

        ~00000101 // 5
        =11111010 // 250
        

        所以 1 变为 0,反之亦然,但在某些情况下,符号位被激活,您会得到意想不到的结果

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2017-05-11
          • 2023-03-18
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-02-13
          相关资源
          最近更新 更多