[英]How to convert a decimal number to binary in Swift?
如何在 Swift 中將 Int 轉換為 UInt8? 例子。 我想將數字 22 轉換為 0b00010110
var decimal = 22
var binary:UInt8 = ??? //What should I write here?
您可以使用帶radix
參數的String
初始值設定項將十進制值轉換為人類可讀的二進制表示:
let num = 22
let str = String(num, radix: 2)
print(str) // prints "10110"
如果你願意,你也可以很容易地用任意數量的零填充它:
斯威夫特 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.1 / Xcode 11
感謝古斯塔沃·塞德勒。 我對他的解決方案的版本補充了可讀性的空格。
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"
我將某人的版本修改為 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"
在這篇文章中經歷了很多答案,但我想知道為什么沒有人提到leadingZeroBitCount
上的 APIleadingZeroBitCount
這將返回特定 UInt 中的零數,例如:
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
}
}
我同意其他人的看法,盡管 for 循環對於重復字符似乎是多余的。
我們可以簡單地使用以下字符串初始化程序:
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
快速 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)
但是如果decimal
將保存超過 255 的值,這將崩潰(發生溢出),因為它是UInt8
可以保存的最大值。
根據您想要實現的目標,您可以編寫
var decimal = 261 // 0b100000101
var binary = UInt8(truncatingBitPattern: decimal) // 0b00000101
結果你會得到0
,因為這個初始值設定項會截斷不太重要的位。
第二個選擇是
var decimal = 256 // 0b100000000
var binary = UInt8(exactly: decimal) // nil
如果發生溢出,此初始化程序將返回nil
結果而不是崩潰。
PS如果你想看到二進制字符串表示使用
String(decimal, radix: 2)
String(binary, radix: 2)
所以我最近出現了這個。 由於各種問題,其他通用解決方案對我不起作用。 無論如何,這是我的解決方案(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 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
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.