Linux 在算术运算和数字运算中,用x';Bash的意思是什么?

Linux 在算术运算和数字运算中,用x';Bash的意思是什么?,linux,bash,Linux,Bash,我很好奇下面的比较到底做了什么,尽可能详细,特别是与0x2和&字符相关的比较,以及它们到底做了什么 if [ $((${nValid} & 0x1)) -eq 1 ]; then #...snip... fi if [ $((${nValid} & 0x2)) -eq 2 ]; then #...snip... fi &是按位AND运算符。因此,您要求在0x1和${nVAlid}返回的值之间进行位and运算 有关按位操作的详细信息,请参见shell脚本将数字解释为十进

我很好奇下面的比较到底做了什么,尽可能详细,特别是与
0x2
&
字符相关的比较,以及它们到底做了什么

if [ $((${nValid} & 0x1)) -eq 1 ]; then
  #...snip...
fi

if [ $((${nValid} & 0x2)) -eq 2 ]; then
  #...snip...
fi

&是按位AND运算符。因此,您要求在0x1和${nVAlid}返回的值之间进行位and运算


有关按位操作的详细信息,请参见

shell脚本将数字解释为十进制(以10为基数),除非该数字具有特殊的前缀或符号。前跟0的数字是八进制(以8为基数)。前面加0x的数字是十六进制(以16为基数)。带有嵌入#的数字计算为基#数(具有范围和符号限制)

因此,在
[$(${nValid}&0x1))-eq 1]
中,
$nValid
0x1
进行and运算,并与十进制
1
进行比较。同样,第二个比较也是如此


阅读和获取详细信息

0x1
0x2
是1和2的十六进制符号。
&
是按位AND运算符。这些行所做的是测试nValid中的值是否设置了最低有效位(0x1)和第二最低有效位(0x2)

该方案如下(C表示法):


其中X是2的幂(而不是十六进制和十进制混合表示法)。

它是在每比特的基础上测试nValid

按位
运算符(
&
)意味着该运算符将逐位执行
比较。因此,如果nValid是字节(8位)值,请查看二进制操作:

nValue & 0b00000001
如果nValue为42,则操作如下所示

(nValue = 0b00101010) & 0b00000001 => 0b00000000 // (does not have the last bit set)
(nValue & 0b00000001) == 0b00000001 // false
第二个(
nValid&0x2

这对于测试变量内的标志非常有用;通常使用
通过隔离位检查标志,使用
组合标志

0b00001000 | 0b00000010 | 0b00000001 => 0b00001011

这可以改写为:

if (( nValid & 2#00000001 )); then
  #...snip...
fi

if (( nValid & 2#00000010 )); then
  #...snip...
fi
选择最适合上下文的二进制位数。如果只检查一位*,则无需测试是否相等。如果十六进制表示法更有意义的话,您仍然可以使用它。在此上下文中,大括号和美元符号不是必需的

您可能希望使用具有有意义名称的常量,而不是硬编码的值:

declare -r FOO=$((2#00000001))
declare -r BAR=$((2#00000010))
if (( nValid & FOO )); then
  #...snip...
fi
if (( nValid & BAR )); then
  #...snip...
fi
*如果同时测试多个位,则需要测试是否相等:

if (( (nValid & (FOO | BAR)) == (FOO | BAR) )); then
  #...snip...
fi
您将需要额外的括号,因为
==
的优先级高于按位运算符

清除和设置Bash中的位:

(( var |= FOO ))    # set the bits in FOO into var
(( var &= ~BAR ))   # clear the bits in BAR from var

你能描述一下当“
$nValid
0x1
进行and运算”时会发生什么情况吗?@tj111:查看这些链接:每个值最终都是用二进制表示的,因此假设二进制中的
$nValid
表示为
1001
0x1
表示为
0001
,这两个操作的
&
将导致:
0001
。看见
declare -r FOO=$((2#00000001))
declare -r BAR=$((2#00000010))
if (( nValid & FOO )); then
  #...snip...
fi
if (( nValid & BAR )); then
  #...snip...
fi
if (( (nValid & (FOO | BAR)) == (FOO | BAR) )); then
  #...snip...
fi
(( var |= FOO ))    # set the bits in FOO into var
(( var &= ~BAR ))   # clear the bits in BAR from var