Хтось знав, чи є вбудована функція Go для перетворення будь-якого з числових типів у форму двійкового числа.
Наприклад, якби 123
було вхідним, рядок "1111011"
був би вихідним.
Хтось знав, чи є вбудована функція Go для перетворення будь-якого з числових типів у форму двійкового числа.
Наприклад, якби 123
було вхідним, рядок "1111011"
був би вихідним.
Відповіді:
strconv
Пакет має FormatInt
, який приймає int64
і дозволяє вказати базу.
n := int64(123)
fmt.Println(strconv.FormatInt(n, 2)) // 1111011
ДЕМО: http://play.golang.org/p/leGVAELMhv
http://golang.org/pkg/strconv/#FormatInt
func FormatInt(i int64, base int) string
FormatInt повертає рядкове представлення i у даній основі для 2 <= base <= 36. Результат використовує малі літери від «a» до «z» для значень цифр> = 10.
fmt.Println(strconv.FormatInt(n, 2))
є -11
, але я хочу формат компліменту двох.
i, err := strconv.ParseInt("1101", 2, 64)
Дивіться також пакет fmt :
n := int64(123)
fmt.Printf("%b", n) // 1111011
s := fmt.Sprintf("%b", 123)
Цей код працює на великих цілих числах *big.Int
:
x := big.NewInt(123)
s := fmt.Sprintf("%b", x)
// s == "1111011"
оскільки *big.Int
реалізує fmt.Formatter
інтерфейс.
package main
import . "fmt"
func main(){
Printf("%d == %08b\n",0,0)
Printf("%d == %08b\n",1,1)
Printf("%d == %08b\n",2,2)
Printf("%d == %08b\n",3,3)
Printf("%d == %08b\n",4,4)
Printf("%d == %08b\n",5,5)
}
призводить до:
0 == 00000000
1 == 00000001
2 == 00000010
3 == 00000011
4 == 00000100
5 == 00000101
Спираючись на відповідь, надану @Mark
Незважаючи на те, що OP запитував, як надрукувати ціле число, я часто хочу переглядати дані, які перевищують 64 біти, без очей:
/* --- Credit to Dave C in the comments --- */
package main
import (
"bytes"
"fmt"
)
func main() {
fmt.Printf("<%s>\n", fmtBits([]byte{0xDE, 0xAD, 0xBE, 0xEF, 0xF0, 0x0D, 0xDE, 0xAD, 0xBE, 0xEF, 0xF0, 0x0D}))
// OUTPUT:
// <11011110 10101101 10111110 11101111 11110000 00001101 11011110 10101101 10111110 11101111 11110000 00001101>
}
func fmtBits(data []byte) []byte {
var buf bytes.Buffer
for _, b := range data {
fmt.Fprintf(&buf, "%08b ", b)
}
buf.Truncate(buf.Len() - 1) // To remove extra space
return buf.Bytes()
}
див. цей код на play.golang.org
[]byte
. Неодноразове додавання до string
подібного, що є неефективним, краще використовувати щось на зразок bytes.Buffer
(або, якщо тільки воно робило провідні нулі, використовуючи просто strconv.AppendInt
з простою []byte
). Викликати strings.TrimSpace
кожну ітерацію, щоб просто обробити єдиний зайвий простір, дуже неефективно. Наприклад, щось на зразок play.golang.org/p/ifobZWv_du на вході 1 кБ швидше в 50 разів і використовує ~ 1/50 пам'яті.
Альтернативним способом прийнятої відповіді буде просто зробити
s := fmt.Sprintf("%b", 123)
fmt.Println(s) // 1111011
Для більш насиченого подання ви можете використовувати unsafe
пакет (настійно не рекомендується) як
a := int64(123)
byteSliceRev := *(*[8]byte)(unsafe.Pointer(&a))
byteSlice := make([]byte, 8)
for i := 0; i < 8; i++ {
byteSlice[i] = byteSliceRev[7 - i]
}
fmt.Printf("%b\n", byteSlice)
Це працює і для від’ємних цілих чисел.
Необхідно використовувати небезпечні вказівники для коректного представлення від’ємних чисел у двійковому форматі.
package main
import (
"fmt"
"strconv"
"unsafe"
)
func bInt(n int64) string {
return strconv.FormatUint(*(*uint64)(unsafe.Pointer(&n)), 2)
}
func main() {
fmt.Println(bInt(-1))
}