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


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.