Konvertieren von einer Ganzzahl in ihre Binärdarstellung

78

Hat jemand eine Idee, ob es in Go eine eingebaute Funktionalität gibt, um von einem der numerischen Typen in seine Binärzahlform zu konvertieren?

Wenn beispielsweise 123die Eingabe wäre, wäre die Zeichenfolge "1111011"die Ausgabe.

Cobie
quelle
Dies erfolgt automatisch. Dezimalzahlen werden konvertiert und in binärer Form verwendet.
QuentinUK
Zahlen in einer Programmiersprache werden bereits in binärer Form gespeichert. Vielleicht wollten Sie sie in Basis 2 ausgeben? Oder 32-Bit-Zweierkomplementbasis 2? Natürlich macht beides keinen Sinn für Gleitkommazahlen, bei denen Sie die Textdarstellung des IEEE unabhängig vom Format wünschen. Oder einfach die Rohbitmuster in einen Stream ausgeben?
Millimoose

Antworten:

114

Das strconvPaket hat FormatInt, das ein akzeptiert int64und Sie können die Basis angeben.

n := int64(123)

fmt.Println(strconv.FormatInt(n, 2)) // 1111011

DEMO: http://play.golang.org/p/leGVAELMhv

http://golang.org/pkg/strconv/#FormatInt

func FormatInt(i int64, base int) string

FormatInt gibt die Zeichenfolgendarstellung von i in der angegebenen Basis für 2 <= Basis <= 36 zurück. Das Ergebnis verwendet die Kleinbuchstaben 'a' bis 'z' für Ziffernwerte> = 10.

Ich hasse Faulheit
quelle
Vielen Dank dafür ... Ich muss die Handbücher genauer lesen.
Cobie
1
Wie man ein negatives int (signiertes int) formatiert, fmt.Println(strconv.FormatInt(n, 2))ist -11, aber ich möchte das Komplimentformat von zwei.
Simin Jie
4
Was ist das Gegenteil davon? Benötige ich die Ganzzahl aus einer Binärzeichenfolge?
Majidarif
1
@majidarif, benutze i, err := strconv.ParseInt("1101", 2, 64)
tobi.g
59

Siehe auch die fmt Paket:

n := int64(123)
fmt.Printf("%b", n)  // 1111011
Kennzeichen
quelle
9
Wie @Luke Antins zeigt, kann die Länge der Binärausgabe durch Hinzufügen einer Zahl zwischen Prozent und b angegeben werden. ZB '% 08b' führt zu 00000001.
Thomas Fankhauser
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)
}

Ergebnisse in:

0 == 00000000
1 == 00000001
2 == 00000010
3 == 00000011
4 == 00000100
5 == 00000101
sjas
quelle
3

Aufbauend auf der Antwort von @Mark

Obwohl das OP gefragt hat, wie eine Ganzzahl gedruckt werden soll, möchte ich häufig Daten im Wert von mehr als 64 Bit anzeigen, ohne dass meine Augen verwirren:

/* --- 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()
}
Siehe diesen Code in play.golang.org
Luke Antins
quelle
1
Wenn Sie einen Hardcode für stdout verwenden möchten, geben Sie ihn einfach in der Schleife aus. Wenn es sich um eine Formatierungsfunktion handelt, muss sie zurückgegeben werden []byte. Das wiederholte Anhängen an ein solches Element stringist ineffizient. Besser ist es, etwas wie ein zu verwenden bytes.Buffer(oder wenn es nur führende Nullen verwendet, nur strconv.AppendIntmit einer Ebene []byte). Es strings.TrimSpaceist sehr ineffizient, jede Iteration nur aufzurufen, um den einzelnen zusätzlichen Speicherplatz zu verwalten. Zum Beispiel ist so etwas wie play.golang.org/p/ifobZWv_du an einem 1-KB-Eingang ~ 50x schneller und verbraucht ~ 1/50 des Speichers.
Dave C
Effizienz ist mir nie in den Sinn gekommen, aber in jeder Hinsicht sind Sie richtig und Ihre Lösung ist viel besser als meine, danke! Mehr als 64-Bit-Daten anzeigen war mein Ziel :)
Luke Antins
2

Ein alternativer Weg für die akzeptierte Antwort wäre einfach zu tun

s := fmt.Sprintf("%b", 123)
fmt.Println(s)                 // 1111011

Für eine reichhaltigere Darstellung können Sie das unsafePaket (stark entmutigt) als verwenden

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)

Dies funktioniert auch für negative Ganzzahlen.

Vaibhav Mishra
quelle
1

Unsichere Zeiger müssen verwendet werden, um negative Zahlen im Binärformat korrekt darzustellen.

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

Soslan
quelle