Перетворення з цілого числа в його двійкове представлення


80

Хтось знав, чи є вбудована функція Go для перетворення будь-якого з числових типів у форму двійкового числа.

Наприклад, якби 123було вхідним, рядок "1111011"був би вихідним.


Це робиться автоматично. Десяткові числа перетворюються і використовуються у двійковій формі.
QuentinUK

Числа в мові програмування вже зберігаються у двійковій формі. Може, ви мали на увазі вивести їх у базі 2? Або 32-розрядна база доповнень 2? Звичайно, ні те, ні інше не матиме сенсу для чисел з плаваючою комою, де ви хочете текстове представлення IEEE незалежно від формату. Або просто вивести необроблені шаблони бітів у потік?
milimoose

Відповіді:


114

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.


велике спасибі за це ... Мені потрібно уважніше прочитати посібники.
cobie

1
Як відформатувати негативний int (підписаний int), fmt.Println(strconv.FormatInt(n, 2))є -11, але я хочу формат компліменту двох.
Simin Jie

4
Що у цьому зворотне? Якщо мені потрібно ціле число з двійкового рядка?
majidarif

1
@majidarif, use i, err := strconv.ParseInt("1101", 2, 64)
tobi.g

62

Дивіться також пакет fmt :

n := int64(123)
fmt.Printf("%b", n)  // 1111011

9
Як показує @Luke Antins, довжину двійкового виводу можна вказати, додавши число між відсотками та b. Наприклад, "% 08b" веде до 00000001.
Томас Фанхаузер,

2
s := fmt.Sprintf("%b", 123)
ahuigo


4
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

3

Спираючись на відповідь, надану @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

1
Якщо ви збираєтеся жорстко кодувати stdout, тоді просто виведіть цикл; якщо це функція форматування, то поверніть її []byte. Неодноразове додавання до stringподібного, що є неефективним, краще використовувати щось на зразок bytes.Buffer(або, якщо тільки воно робило провідні нулі, використовуючи просто strconv.AppendIntз простою []byte). Викликати strings.TrimSpaceкожну ітерацію, щоб просто обробити єдиний зайвий простір, дуже неефективно. Наприклад, щось на зразок play.golang.org/p/ifobZWv_du на вході 1 кБ швидше в 50 разів і використовує ~ 1/50 пам'яті.
Dave C

Ефективність мені ніколи не приходила в голову, але з усіх пунктів ви маєте рацію, і ваше рішення набагато краще, ніж моє, дякую! Моєю метою було відображення даних на суму понад 64 біти :)
Люк Антінс

2

Альтернативним способом прийнятої відповіді буде просто зробити

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)

Це працює і для від’ємних цілих чисел.


1

Необхідно використовувати небезпечні вказівники для коректного представлення від’ємних чисел у двійковому форматі.

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))
}

https://play.golang.org/p/GxXjjWMyC4x

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.