sport - ¿Cómo convertir un número decimal a binario en Swift?
swift sport (10)
¿Cómo puedo convertir Int a UInt8 en Swift? Ejemplo. Quiero convertir el número 22 en 0b00010110
var decimal = 22
var binary:UInt8 = ??? //What should I write here?
Así es como lo haría:
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
Así que tuve esto surgido recientemente. Las otras soluciones genéricas no funcionaron para mí, debido a varios problemas. De todos modos, aquí está mi solución (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))
}
}
}
Pruebas:
// 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)
Dado que ninguna de las soluciones contempla números negativos, se me ocurrió una solución simple que básicamente lee la representación interna del número y se ajusta automáticamente al ancho de su tipo. Esto debería funcionar en todos los tipos de 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
}
}
Ejemplos:
UInt8(22).binaryDescription // "0b00010110"
Int8(60).binaryDescription // "0b00111100"
Int8(-60).binaryDescription // "0b11000100"
Int16(255).binaryDescription // "0b0000000011111111"
Int16(-255).binaryDescription // "0b1111111100000001"
Estoy de acuerdo con los demás, aunque el for-loop parece redundante para repetir un personaje.
simplemente podemos ir con el siguiente inicializador de cadenas:
init(count count: Int, repeatedValue c: Character)
ejemplo de uso:
let string = String(count: 5, repeatedValue: char)
Aquí hay un ejemplo completo:
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)
Modifiqué la versión de alguien para acelerar 3.0 utilicé el inicializador correcto para crear una cadena con valores repetidos
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"
Modifiqué tu versión a Swift 2.0 para contar las cadenas y agregué una verificación de longitud:
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
}
}
}
No hay diferencia entre los sistemas numéricos binarios y decimales, cuando trabajas con variables hasta que quieras visualizarlas o si quieres convertir tipos que puedan contener diferentes cantidades de bits.
En tu caso es suficiente para escribir
var decimal = 22
var binary = UInt8(decimal)
Pero esto se bloqueará (se produce un desbordamiento) si el decimal
tendrá un valor superior a 255, porque es el valor máximo que UInt8
puede contener.
Dependiendo de lo que quieras lograr, puedes escribir
var decimal = 261 // 0b100000101
var binary = UInt8(truncatingBitPattern: decimal) // 0b00000101
Obtendrás 0
como resultado, porque este inicializador truncará bits menos significativos.
La segunda opción es
var decimal = 256 // 0b100000000
var binary = UInt8(exactly: decimal) // nil
Este inicializador devuelve un resultado nil
lugar de bloquearse, si ocurre un desbordamiento.
PD Si desea ver la representación de cadenas binarias, use
String(decimal, radix: 2)
String(binary, radix: 2)
Puede convertir el valor decimal en una representación binaria legible para el ser humano utilizando el inicializador de String
que toma un parámetro de radix
:
let num = 22
let str = String(num, radix: 2)
print(str) // prints "10110"
Si quisieras, también podrías rellenarlo con cualquier número de ceros con bastante facilidad:
func pad(string : String, toSize: Int) -> String {
var padded = string
for _ in 0..<(toSize - string.characters.count) {
padded = "0" + padded
}
return padded
}
let num = 22
let str = String(num, radix: 2)
print(str) // 10110
pad(string: str, toSize: 8) // 00010110
Si quiere que el binary
tenga el valor de 22
, simplemente binary = 0b00010110
: binary = 22
o podría escribirlo como binary = 0b00010110
; las dos declaraciones son equivalentes.
veloz 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] )
resultado
15 00001111
240 11110000
bueno para ti ~