How to convert a decimal number to binary in Swift?

Swift

Swift Problem Overview


How can I convert Int to UInt8 in Swift? Example. I want to convert number 22 to 0b00010110

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

Swift Solutions


Solution 1 - Swift

You can convert the decimal value to a human-readable binary representation using the String initializer that takes a radix parameter:

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

If you wanted to, you could also pad it with any number of zeroes pretty easily as well:

Swift 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

Solution 2 - Swift

Swift 5.1 / Xcode 11

Thanks Gustavo Seidler. My version of his solution is complemented by spaces for readability.

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

Examples:

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"

Solution 3 - Swift

I agree with the others, Although the for-loop seems redundant for repeating a character.
we can simply go with the following String initialiser:

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

usage example:

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

Here is a full example:

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)

Solution 4 - Swift

I modified someone's version to swift 3.0 used the correct initializer for creating a string with repeated values

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"

Solution 5 - Swift

Since none of the solutions contemplate negative numbers, I came up with a simple solution that basically reads the number's internal representation and pads it automatically to the width of its type. This should work on all BinaryInteger types.

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

Examples:

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

Solution 6 - Swift

Went through a lot of answers on this post but I wonder why haven't anyone mentioned the API leadingZeroBitCount on FixedWidthInteger

This returns the number of zeros in specific UInt eg:

UInt(4).leadingZeroBitCount //61

UInt16(4).leadingZeroBitCount //13

Swift Version

4.1

USAGE

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

UNDER THE HOOD

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

Solution 7 - Swift

If you want binary to have the value of 22, just assign it that: binary = 22 or you could write it as binary = 0b00010110; the two statements are equivalent.

Solution 8 - Swift

Here's how I would do it:

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

Solution 9 - Swift

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

result

15 00001111

240 11110000

good for you~

Solution 10 - Swift

There is no difference between binary and decimal numeral systems, when you're working with variables until you want to visualize them or if you want to convert types which can hold different ammount of bits.

In your case is enough to write

var decimal = 22
var binary = UInt8(decimal)

But this will crash (overflow happens) if decimal will hold a value more than 255, because it is maximum value which UInt8 can hold.

Depending on what you want to achieve you can write

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

You'll get 0 as a result, because this initializer will truncate less significant bits.

Second option is

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

This initializer returns nil result instead of crashing, if overflow happens.

P.S. If you want to see binary string representation use

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

Solution 11 - Swift

So I had this come up recently. The other generic solutions didn't work for me, due to various issues. Anyway, here's my solution (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))
    }
  }
}

Tests:

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

Solution 12 - Swift

I modified your version to Swift 2.0 count on strings and added a length check:

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

Solution 13 - Swift

Most answers here forget to account for 0, and outputs a representation there is too long.

Based on the answer by @karwag I present:

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

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionsubdanView Question on Stackoverflow
Solution 1 - SwiftCraig OtisView Answer on Stackoverflow
Solution 2 - SwiftA.KantView Answer on Stackoverflow
Solution 3 - SwiftTomerBuView Answer on Stackoverflow
Solution 4 - SwiftA'sa DickensView Answer on Stackoverflow
Solution 5 - SwiftGustavo SeidlerView Answer on Stackoverflow
Solution 6 - SwiftthesummersignView Answer on Stackoverflow
Solution 7 - SwiftScott HunterView Answer on Stackoverflow
Solution 8 - SwiftAlexanderView Answer on Stackoverflow
Solution 9 - SwiftSINKUK KANGView Answer on Stackoverflow
Solution 10 - SwiftSilmarilView Answer on Stackoverflow
Solution 11 - SwiftkarwagView Answer on Stackoverflow
Solution 12 - SwifthibentoView Answer on Stackoverflow
Solution 13 - SwiftmagnuskahrView Answer on Stackoverflow