정수에서 이진 표현으로 변환


80

Go에 숫자 유형 중 하나를 이진 숫자 형식으로 변환하기위한 내장 기능이 있는지 누구든지 아이디어를 얻었습니다.

예를 들어 123입력 인 경우 문자열 "1111011"이 출력이됩니다.


이것은 자동으로 수행됩니다. 십진수는 이진 형식으로 변환되어 사용됩니다.
QuentinUK

프로그래밍 언어의 숫자는 이미 이진 형식으로 저장되어 있습니다. 아마도 2 진법으로 출력하려고했을까요? 아니면 32 비트 2의 보수베이스 2? 물론 어떤 형식이든 IEEE의 텍스트 표현을 원하는 부동 소수점 숫자에는 어느 것도 의미가 없습니다. 아니면 그냥 원시 비트 패턴을 스트림으로 출력합니까?
millimoose

답변:


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는 2 <= base <= 36에 대해 주어진 기수로 i의 ​​문자열 표현을 반환합니다. 결과는 숫자 값> = 10에 대해 소문자 'a'에서 'z'를 사용합니다.


감사합니다 ... 매뉴얼을 좀 더주의 깊게 읽어야합니다.
cobie

1
음수 int (signed int)를 포맷하는 방법 fmt.Println(strconv.FormatInt(n, 2))-11이지만 2의 칭찬 형식을 원합니다.
Simin Jie

4
그 반대는 무엇입니까? 이진 문자열의 정수가 필요한 경우?
majidarif

1
@majidarif 사용 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로 이어집니다.
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)
}

결과 :

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비슷한 것에 반복적으로 추가 하는 것은 비효율적이며, a 와 같은 것을 사용하는 것이 더 좋습니다 bytes.Buffer(또는 선행 0을 사용하는 경우에만 strconv.AppendInt일반 사용 []byte). strings.TrimSpace단일 추가 공간을 처리하기 위해 각 반복을 호출 하는 것은 매우 비효율적입니다. 예를 들어 1kB 입력에서 play.golang.org/p/ifobZWv_du 와 같은 것은 ~ 50 배 빠르며 메모리의 ~ 1 / 50를 사용합니다.
Dave C

효율성은 내 마음을 넘어선 적이 없지만 모든면에서 당신은 정확하고 당신의 솔루션은 내 것보다 훨씬 낫습니다. 감사합니다! 데이터의 표시 더 다음 64 비트 가치이었다 나의 목표 :
누가 복음 Antins

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

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.