programing

스위프트에서 십진수를 이진수로 변환하는 방법은 무엇입니까?

lastcode 2023. 8. 5. 10:17
반응형

스위프트에서 십진수를 이진수로 변환하는 방법은 무엇입니까?

Swift에서 Int를 UInt8로 변환하려면 어떻게 해야 합니까?예.22번을 0b00010110으로 바꾸고 싶습니다.

var decimal = 22
var binary:UInt8 = ??? //What should I write here?

다음을 사용하여 십진수 값을 사람이 읽을 수 있는 이진 표현으로 변환할 수 있습니다.String를 사용하는 이니셜라이저radix매개변수:

let num = 22
let str = String(num, radix: 2)
print(str) // prints "10110"

원하는 경우 임의의 수의 0으로 쉽게 패딩할 수도 있습니다.

스위프트 5

func pad(string : String, toSize: Int) -> String {
  var padded = string
  for _ in 0..<(toSize - string.count) {
    padded = "0" + padded
  }
    return padded
}

let num = 22
let str = String(num, radix: 2)
print(str) // 10110
pad(string: str, toSize: 8)  // 00010110

스위프트 5 / Xcode 14

구스타보 세이들러에게 감사합니다.그의 솔루션에 대한 제 버전은 가독성을 위한 공간으로 보완됩니다.

extension BinaryInteger {
    var binaryDescription: String {
        var binaryString = ""
        var internalNumber = self
        var counter = 0
        
        for _ in (1...self.bitWidth) {
            binaryString.insert(contentsOf: "\(internalNumber & 1)", at: binaryString.startIndex)
            internalNumber >>= 1
            counter += 1
            if counter % 4 == 0 {
                binaryString.insert(contentsOf: " ", at: binaryString.startIndex)
            }
        }

        return binaryString
    }
}

예:

UInt8(9).binaryDescription      // "0000 1001"
Int8(5).binaryDescription       // "0000 0101"
UInt16(1945).binaryDescription  // "0000 0111 1001 1001"

Int16(14).binaryDescription     // "0000 0000 0000 1110"
Int32(6).binaryDescription      // "0000 0000 0000 0000 0000 0000 0000 0110"
UInt32(2018).binaryDescription  // "0000 0000 0000 0000 0000 0111 1110 0010"

이 게시물에 대한 많은 답변을 거쳤는데 왜 아무도 API에 대해 언급하지 않았는지 궁금합니다.leadingZeroBitCount고정 너비 정수

특정 UI Integ에서 0의 수를 반환합니다.

UInt(4).leadingZeroBitCount //61

UInt16(4).leadingZeroBitCount //13

스위프트 버전

4.1

사용.

let strFive = String.binaryRepresentation(of: UInt8(5))
print(strFive) // Prints: 00000101 

후드 아래

extension String {

    static func binaryRepresentation<F: FixedWidthInteger>(of val: F) -> String {

        let binaryString = String(val, radix: 2)

        if val.leadingZeroBitCount > 0 {
            return String(repeating: "0", count: val.leadingZeroBitCount) + binaryString
        }

        return binaryString
    }
}

나는 누군가의 버전을 swift 3.0으로 수정했습니다. 올바른 이니셜라이저를 사용하여 반복되는 값을 가진 문자열을 만들었습니다.

extension String {
    func pad(with character: String, toLength length: Int) -> String {
        let padCount = length - self.characters.count
        guard padCount > 0 else { return self }

        return String(repeating: character, count: padCount) + self
    }
}

String(37, radix: 2).pad(with: "0", toLength: 8) // "00100101"

어떤 해결책도 음수를 고려하지 않기 때문에, 저는 기본적으로 숫자의 내부 표현을 읽고 자동으로 숫자의 너비에 맞게 패드를 붙이는 간단한 해결책을 생각해냈습니다.모두에게 효과가 있을 것입니다.BinaryInteger종류들.

extension BinaryInteger {
    var binaryDescription: String {
        var binaryString = ""
        var internalNumber = self
        for _ in (1...self.bitWidth) {
            binaryString.insert(contentsOf: "\(internalNumber & 1)", at: binaryString.startIndex)
            internalNumber >>= 1
        }
        return "0b" + binaryString
    }
}

예:

UInt8(22).binaryDescription     // "0b00010110"
Int8(60).binaryDescription      // "0b00111100"
Int8(-60).binaryDescription     // "0b11000100"
Int16(255).binaryDescription    // "0b0000000011111111"
Int16(-255).binaryDescription   // "0b1111111100000001"

저는 다른 사람들의 의견에 동의합니다. 비록 for-loop은 캐릭터를 반복하는 데 불필요해 보이지만요.
다음 String 이니셜라이저를 사용하면 됩니다.

init(count count: Int, repeatedValue c: Character)

사용 예:

let string = String(count: 5, repeatedValue: char)

다음은 전체 예입니다.

let someBits: UInt8 = 0b00001110
let str = String(someBits, radix:2) //binary base
let padd = String(count: (8 - str.characters.count), repeatedValue: Character("0")) //repeat a character
print(padd + str)

네가 원한다면binary의 가치가 있습니다22다음과 같이 할당합니다.binary = 22아니면 당신은 그것을 쓸 수 있습니다.binary = 0b00010110두 진술은 동등합니다.

다음과 같은 방법이 있습니다.

extension String {
    public func pad(with padding: Character, toLength length: Int) -> String {
        let paddingWidth = length - self.characters.count
        guard 0 < paddingWidth else { return self }

        return String(repeating: padding, count: paddingWidth) + self
    }
}

String(0b1010, radix: 2).pad(with: "0", toLength: 8) //00001010

그래서 저는 최근에 이런 이야기를 하게 되었습니다.다른 일반적인 솔루션은 여러 가지 문제로 인해 저에게 효과가 없었습니다.어쨌든 다음은 제 솔루션입니다(Swift 4).

extension String {
  init<B: FixedWidthInteger>(fullBinary value: B) {
    self = value.words.reduce(into: "") {
      $0.append(contentsOf: repeatElement("0", count: $1.leadingZeroBitCount))
      $0.append(String($1, radix: 2))
    }
  }
}

테스트:

// result: 0000000000000000000000000000000000000000000000000000000000001001
String(fullBinary: 9)
// result: 1111111111111111111111111111111111111111111111111111111100000000
String(fullBinary: -256)

// result: 1111111111111111111111111111111111111111111111111101100011110001
String(fullBinary: -9999)
// result: 0000000000000000000000000000000000000000000000000010011100001111
String(fullBinary: 9999)

// result: 1100011000000000000000000000000000000000000011110110100110110101
String(fullBinary: 14267403619510741429 as UInt)

swift 4.1

extension String {
    public func pad(with padding: Character, toLength length: Int) -> String {
        let paddingWidth = length - self.count
        guard 0 < paddingWidth else { return self }

        return String(repeating: padding, count: paddingWidth) + self
    }
}


extension UInt8 {
     public func toBits() -> String
     {
          let a = String( self, radix : 2 )
          let b = a.pad(with: "0", toLength: 8)
          return b
     }
}

func showBits( _ list: [UInt8] )
{
    for num in list
    {
        showBits(num)
    }
}

func showBits( _ num: UInt8 )
{
    //print(num, String( num, radix : 2 ))
    print( "\(num) \t" +   num.toBits())
}

let initialBits :UInt8 = 0b00001111
let invertedBits = ~initialBits
showBits( [initialBits, invertedBits] )

결과

15 00001111

240 11110000

잘됐네요.

이진수와 십진수 시스템 사이에는 차이가 없습니다. 변수를 시각화하기 전까지 변수를 사용하거나 다른 비트 양을 저장할 수 있는 유형을 변환하려는 경우입니다.

당신의 경우에는 쓰기에 충분합니다.

var decimal = 22
var binary = UInt8(decimal)

그러나 이는 다음과 같은 경우 충돌합니다(오버플로 발생).decimal255 이상의 값을 보유합니다. 왜냐하면 다음과 같은 최대값이기 때문입니다.UInt8견딜 수 있습니다.

당신이 성취하고 싶은 것에 따라 당신은 쓸 수 있습니다.

var decimal = 261 // 0b100000101
var binary = UInt8(truncatingBitPattern: decimal) // 0b00000101

얻게 될 것입니다.0결과적으로 이 이니셜라이저는 덜 중요한 비트를 잘라내기 때문입니다.

두 번째 옵션은

var decimal = 256  // 0b100000000
var binary = UInt8(exactly: decimal) // nil

는 이이셜이반환다니됩가를 반환합니다.nil오버플로가 발생할 경우 충돌 대신 결과가 발생합니다.

추신. 이진 문자열 표현을 보려면 다음을 사용합니다.

String(decimal, radix: 2)
String(binary, radix: 2)

나는 당신의 버전을 Swift 2.0 count on strings로 수정하고 길이 검사를 추가했습니다.

extension String {
 func pad(length: Int) -> String {
    let diff = length - self.characters.count
    if diff > 0 {
        var padded = self
        for _ in 0..<diff {
            padded = "0" + padded
        }
        return padded
    } else {
        return self
    }
 }
}

여기서 대부분의 답변은 0을 설명하는 것을 잊어버리고 너무 긴 표현을 출력합니다.

제가 제시한 @karwag의 답변에 기초하여:

extension FixedWidthInteger {
    var binaryStringRepresentation: String {
        words.reduce(into: "") {
            $0.append(contentsOf: repeatElement("0", count: $1.leadingZeroBitCount))
            if $1 != 0 {
                $0.append(String($1, radix: 2))
            }
        }
    }
}

좀 복잡하지만, 매우 빠릅니다.문자열에 공백을 남기지 않고 4비트마다 구분됩니다.

extension BinaryInteger {

    var binaryDescription: String {
        var string = ""
        var num = self
        let range: UInt64
        switch self.bitWidth {
            case 8:  range = 0x80
            case 16: range = 0x8000
            case 32: range = 0x80000000
            case 64: range = 0x8000000000000000
            default: range = 0x0
        }   
        
        if Self.isSigned {          
            let mask = Self(range / 2)
            let last = num & 1
            num >>= 1
            
            for i in 1...self.bitWidth-1 {
                string.append("\(num & mask == mask ? 1 : 0)")
                num <<= 1
                if i % 4 == 0 { string.append(" ") }
            }
            
            string.append("\(last)")
                        
        } else { // Unsigned
    
            let mask = Self(range)

            for i in 1...self.bitWidth {
                string.append("\(num & mask == mask ? 1 : 0)")
                num <<= 1
                if i % 4 == 0 { string.append(" ") }
            }
            
            string = String(string.dropLast())          
        }
        
        return string
    }   
}

예:

UInt8(245).binaryDescription  // 1111 0101
Int8(108).binaryDescription   // 0110 1100

언급URL : https://stackoverflow.com/questions/26181221/how-to-convert-a-decimal-number-to-binary-in-swift

반응형