【问题标题】:What is the signification of ~ and & binary operator in C [duplicate]C中~和&二元运算符的含义是什么[重复]
【发布时间】:2020-05-26 23:34:29
【问题描述】:

我最近不得不在 c 中使用 sbrk() 函数 我必须计算我将用于在内存中分配空间的大小。 经过一番研究,我发现了这行代码:

size_t calc_size = ((size) + ((4096) - 1)) & ~((4096) - 1);

尽管我搜索了理解运算符“~”和“&”的含义,但我在 c 中的水平很平均,但我找不到明确的解释,确切地说是 ~ 运算符。您能帮我了解正在执行的操作吗?

【问题讨论】:

  • 至于代码本身的作用,基本上是四舍五入到最近的4K边界。 (4096 是 2¹²,这意味着它是一个 1 后跟 12 个二进制零,所以 4096-1 是一个有 12 个二进制 1 的数字。它的补码 ~ 是相反的,所以用它与 & 进行与运算得到 12结果的最低位为零。预先加法使其向上而不是向下舍入。)

标签: c


【解决方案1】:

尽管我搜索了解运算符“~”和“&”的含义,

它们分别是按位非和按位与运算符。它们与逻辑非 (!) 和逻辑与 (&&) 的不同之处在于它们作用于每个单独的位(因此得名)。还有按位或 (|) 和异或 (^) 运算符。例子:

int a = 0x5A;      // a = 01011010
int b = ~a;        // b = 10100101, i.e. bits of a inverted
int c = a & b;     // c = 00000000, i.e. bits of a and b ANDed together
int d = a | b;     // d = 11111111, i.e. bits of a and b ORed together
int e = a ^ 0x3D;  // e = 01100110, i.e. bits of a XORed with 00111100   

您能帮我了解正在执行的操作吗?

代码将size转换为4096的倍数。sbrk()函数调整分配给进程的内存量,4 KB是典型的虚拟内存页面大小,因此增加内存是有意义的4K 增量。这里的想法似乎是在请求的size 上加上4095,这样即使是1 字节的请求也会提升为整个4096 字节的块,然后消除低位,从而得到4K 的倍数。为了更好地理解这一点,请为size 插入一些不同的值,然后看看你得到的calc_size 的值。

【讨论】:

    【解决方案2】:

    ~ 是按位非运算符。它反转其操作数中的所有位。

    至于在这个表达式的上下文中是什么意思:

    size_t calc_size = ((size) + ((4096) - 1)) & ~((4096) - 1);
    

    这会将size 向上取整到最接近的 4096 倍数。

    首先让我们看看~((4096) - 1) 使用二进制表示。 4096 是:

    0001000000000000
    

    (为简单起见,我只显示最低的 16 位。任何高阶位都与最左边的位相同)。现在减 1:

    0000111111111111
    

    并申请~:

    1111000000000000
    

    此值随后用作清除最低 12 位的位掩码,即结果将是 4096 的倍数。

    之后,将 4095 添加到 size。如果它已经是 4096 的倍数,这将导致仅设置掩码将删除的低 12 位。如果不是,则加法将进位到第 13 位,向上舍入,掩码再次删除低位。

    【讨论】:

    • 只是一个小注解:'After that' 意味着二元运算符的右操作数在左操作数之前计算,但实际上这是定义的实现...
    【解决方案3】:

    & 是 AND 位运算符。它的工作原理是这样的:

      0101
      0011
    = 0001
    

    &&的逻辑是一样的,只不过是一点一点的操作。

    ~ 是 NOT 位运算符,方式相同:

      0111
    = 1000
    

    【讨论】:

      猜你喜欢
      • 2015-07-16
      • 2019-09-12
      • 1970-01-01
      • 2021-04-09
      • 2011-08-25
      • 2021-04-14
      • 1970-01-01
      • 1970-01-01
      • 2021-03-29
      相关资源
      最近更新 更多