位运算
TIP
在学习本文之前, 保证你已经了解了二进制的内容.
位运算顾名思义就是对位进行运算.
在日常工作中极少会使用到位操作, 仅在一些库的源码中会出现, 比如涉及到算法和加密的库就会大量使用位运算, 为了方便 对这些库的源代码的理解, 因此有必要掌握位运算.
二进制数之间的运算都是以 32 位二进制数进行运算, 如果两个二进制数位数不相等则位数少的那一个全部补 0.
运算符 | 名称 | 描述 |
---|---|---|
& | 位与 | 同位都为 1 则为 1, 否则为 0 |
| | 位或 | 同位都为 0 则为 0, 否则为 1 |
^ | 位亦或 | 同位不相等为 1, 相等为 0 |
~ | 按位非 | |
<< | 向左移位 | |
>> | 向右移位 | |
>>> | 零填充向右移位 |
位与
按位与(&)运算符在两个操作数对应的二进位都为 1 时,该位的结果值才为 1。
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051
<template>
<section>
<div>输入十进制</div>
<div>
<input class="input" type="number" v-model="val1" />
&
<input class="input" type="number" v-model="val2" />
</div>
<div>
<VBinNumber :value="valBin1" />
<VBinNumber :value="valBin2" />
<div>↓</div>
<VBinNumber :value="valBinResult" />
<div>↓</div>
<div>结果: {{ (val1 ?? 0) & (val2 ?? 0) }}</div>
</div>
</section>
</template>
<script lang="ts" setup>
import { shallowRef, watch } from 'vue'
const val1 = shallowRef<number>()
const val2 = shallowRef<number>()
const valBin1 = shallowRef('')
const valBin2 = shallowRef('')
const valBinResult = shallowRef('')
watch([val1, val2], ([v1, v2]) => {
let bin1 = (v1 || 0).toString(2)
let bin2 = (v2 || 0).toString(2)
bin1 = '0'.repeat(32 - bin1.length) + bin1
bin2 = '0'.repeat(32 - bin2.length) + bin2
valBin1.value = bin1
valBin2.value = bin2
valBinResult.value = ''
let i = -1
while (++i < 32) {
valBinResult.value += bin1[i] === '1' && bin2[i] === '1' ? '1' : '0'
}
})
</script>
位或
按位或(|)运算符在其中一个或两个操作数对应的二进制位为 1 时,该位的结果值为 1。
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950
<template>
<section>
<div>输入十进制</div>
<div>
<input class="input" type="number" v-model="val1" />
|
<input class="input" type="number" v-model="val2" />
</div>
<div>
<VBinNumber :value="valBin1" />
<VBinNumber :value="valBin2" />
<div>↓</div>
<VBinNumber :value="valBinResult" />
<div>↓</div>
<div>结果: {{ (val1 ?? 0) | (val2 ?? 0) }}</div>
</div>
</section>
</template>
<script lang="ts" setup>
import { shallowRef, watch } from 'vue'
const val1 = shallowRef<number>()
const val2 = shallowRef<number>()
const valBin1 = shallowRef('')
const valBin2 = shallowRef('')
const valBinResult = shallowRef('')
watch([val1, val2], ([v1, v2]) => {
let bin1 = (v1 || 0).toString(2)
let bin2 = (v2 || 0).toString(2)
bin1 = '0'.repeat(32 - bin1.length) + bin1
bin2 = '0'.repeat(32 - bin2.length) + bin2
valBin1.value = bin1
valBin2.value = bin2
valBinResult.value = ''
let i = -1
while (++i < 32) {
valBinResult.value += bin1[i] === '1' || bin2[i] === '1' ? '1' : '0'
}
})
</script>
位亦或
按位异或(^)运算符在两个操作数有且仅有一个对应的二进制位为 1 时,该位的结果值为 1。
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051
<template>
<section>
<div>输入十进制</div>
<div>
<input class="input" type="number" v-model="val1" />
^
<input class="input" type="number" v-model="val2" />
</div>
<div>
<VBinNumber :value="valBin1" />
<VBinNumber :value="valBin2" />
<div>↓</div>
<VBinNumber :value="valBinResult" />
<div>↓</div>
<div>结果: {{ (val1 ?? 0) ^ (val2 ?? 0) }}</div>
</div>
</section>
</template>
<script lang="ts" setup>
import { shallowRef, watch } from 'vue'
const val1 = shallowRef<number>()
const val2 = shallowRef<number>()
const valBin1 = shallowRef('')
const valBin2 = shallowRef('')
const valBinResult = shallowRef('')
watch([val1, val2], ([v1, v2]) => {
let bin1 = (v1 || 0).toString(2)
let bin2 = (v2 || 0).toString(2)
bin1 = '0'.repeat(32 - bin1.length) + bin1
bin2 = '0'.repeat(32 - bin2.length) + bin2
valBin1.value = bin1
valBin2.value = bin2
valBinResult.value = ''
let i = -1
while (++i < 32) {
valBinResult.value += bin1[i] !== bin2[i] ? '1' : '0'
}
})
</script>
位非
按位非运算符(~)将操作数的位反转。如同其他位运算符一样,它将操作数转化为 32 位的有符号整型。
12345678910111213141516171819202122232425262728293031323334353637383940
<template>
<section>
<div>输入十进制</div>
<div>
~ <input class="input" type="number" v-model="val" />
</div>
<div>
<VBinNumber :value="valBin" />
<div>↓</div>
<VBinNumber :value="valBinResult" />
<div>↓</div>
<div>结果: {{ ~(val ?? 0) }}</div>
</div>
</section>
</template>
<script lang="ts" setup>
import { shallowRef, watch } from 'vue'
const val = shallowRef<number>()
const valBin = shallowRef('')
const valBinResult = shallowRef('')
watch(val, v => {
let bin = (v || 0).toString(2)
bin = ((v || 0) >= 0 ? '0' : '1') + '0'.repeat(31 - bin.length) + bin
valBin.value = bin
valBinResult.value = ''
let i = -1
while (++i < bin.length) {
valBinResult.value += bin[i] === '0' ? '1' : '0'
}
})
</script>