大家好
任务是将数字的第 i 位更改为 1 或 0。我这样做了,但让我感到困惑的是,有很多类型转换和代码,原则上,这样的任务很多。还能怎么做?
package main
import (
"fmt"
"log"
"strconv"
)
func IntToBits(num int) string {
return strconv.FormatInt(int64(num), 2)
}
func bitsToInt(s string) int64 {
newVal, err := strconv.ParseInt(s, 2, 64)
if err != nil {
log.Fatal(err)
}
return newVal
}
func changeOneBit(num, position, newBit int) int64 {
if position > 0 && num == 0 {
return int64(num)
}
if newBit > 1 || newBit < 0 {
log.Println("Новый бит может быть только 1 или 0")
return int64(num)
}
bits := []byte(IntToBits(num))
fmt.Printf("Было \t %s(%v)\n", string(bits), num)
if position >= len(bits) {
log.Printf("В числе %v нет %v разрядов. Разярядов в числе %v только %v\n", num, position, num, len(bits))
return int64(num)
}
newB := []byte(IntToBits(newBit))
bits[position] = newB[0]
newVal := bitsToInt(string(bits))
fmt.Printf("Стало \t %s(%v)\n", string(bits), newVal)
return newVal
}
func main(){
log.Println(changeOneBit(12, 3, 1)) //8
}
为了只改变一个第 k 位,您需要创建一个掩码 - 一个具有这样一组位的数字,当执行相应的按位运算时,只有所需的位会改变,而其余的位将保持不变。
对于使用按位 OR 的位集操作
0b00001000
,这是形式的掩码0b11110111
第一个很容易通过将 1 移动 k 个位置来获得。
第二个 - 一点一点地反转第一个。
示例:您需要设置第三位
掩码的零位的或操作不会改变数字的相应位。
现在,结果,我们将重置相同的位
掩码的单个位的与操作不会更改数字的相应位。
在这两种情况下,除了第三位之外,其他所有位都保持不变。