按位补码运算符(〜波浪号)如何工作? 您所在的位置:网站首页 c语言感叹号 按位补码运算符(〜波浪号)如何工作?

按位补码运算符(〜波浪号)如何工作?

2023-11-28 10:39| 来源: 网络整理| 查看: 265

tl; dr ~翻转位。结果,标志改变了。~2是负数(0b..101)。要输出负数ruby打印-,然后二进制补码~2:-(~~2 + 1) == -(2 + 1) == 3。正数按原样输出。

有一个内部值及其字符串表示形式。对于正整数,它们基本上重合:

irb(main):001:0> '%i' % 2 => "2" irb(main):002:0> 2 => 2

后者等效于:

irb(main):003:0> 2.to_s "2"

~翻转内部值的位。2是0b010。~2是0b..101。两个点(..)代表无数个1。由于结果的最高有效位(MSB)为,因此1结果为负数((~2).negative? == true)。要输出负数,将ruby打印-,然后是内部值的二进制补码。二进制补码是通过翻转位然后加来计算的1。的补码0b..101为3。因此:

irb(main):005:0> '%b' % 2 => "10" irb(main):006:0> '%b' % ~2 => "..101" irb(main):007:0> ~2 => -3

总结起来,它会翻转位,从而改变符号。要输出负数,它会打印-,然后~~2 + 1(~~2 == 2)。

之所以这样ruby输出负数,是因为它将存储的值视为绝对值的二进制补码。换句话说,存储的是0b..101。这是一个负数,因此是某个值的二进制补码x。要找到x,它做的补码0b..101。这是的二进制补码x。哪个是x(例如~(~2 + 1) + 1 == 2)。

如果您申请~一个负数,它只会翻转位(尽管如此会改变符号):

irb(main):008:0> '%b' % -3 => "..101" irb(main):009:0> '%b' % ~-3 => "10" irb(main):010:0> ~-3 => 2

更令人困惑的是~0xffffff00 != 0xff(或MSB等于的任何其他值1)。让我们简化一下:~0xf0 != 0x0f。那是因为它被视为0xf0正数。这实际上是有道理的。因此,~0xf0 == 0x..f0f。结果为负数。的补码0x..f0f为0xf1。所以:

irb(main):011:0> '%x' % ~0xf0 => "..f0f" irb(main):012:0> (~0xf0).to_s(16) => "-f1"

如果您不打算对结果应用按位运算符,则可以考虑将其~视为-x - 1运算符:

irb(main):018:0> -2 - 1 => -3 irb(main):019:0> --3 - 1 => 2

但这可以说没有多大用处。

一个示例假设您得到一个8位(为简单起见)网络掩码,并且您要计算的数量0。您可以通过翻转位并调用bit_length(0x0f.bit_length == 4)来计算它们。但是~0xf0 == 0x..f0f,因此我们必须删除不需要的位:

irb(main):014:0> '%x' % (~0xf0 & 0xff) => "f" irb(main):015:0> (~0xf0 & 0xff).bit_length => 4

或者,您可以使用XOR运算符(^):

irb(main):016:0> i = 0xf0 irb(main):017:0> '%x' % i ^ ((1 "f"


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有