Поменять i бит числа на 1 или 0
Всем привет
Стоит задача Поменять 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
}
Ответы (1 шт):
Для того, чтобы поменять только один k-й бит, нужно создать маску - число с таким набором битов, что при выполнении соответствующей побитовой операции изменится только нужный бит, а остальные останутся неизменными.
Для операции установки бита c помощью побитового OR это маска вида 0b00001000, а для операции сброса бита c помощью побитового AND маска вида 0b11110111
Первую легко получить, сдвинув единицу на k позиций.
А вторую - побитово инвертировав первую.
Пример: нужно установить третий бит
01010110
^ вот этот
mask=00000001 << 3 = 00001000
01010110 or
00001000
--------
01011110
Операция or c нулевыми битами маски не меняет соответствующие биты числа.
Теперь в результате сбросим это же бит
mask = not(00000001 << 3) = not(00001000) = 11110111
01011110 and
11110111
--------
01010110
Операция and c единичными битами маски не меняет соответствующие биты числа.
В обоих случаях все биты, кроме третьего, остались прежними