在Swift中转换十进制、二进制和十六进制

32

我想知道最有效的代码方法是怎样将以下内容(在Swift 2中)进行转换:

  • 十进制转二进制
  • 二进制转十进制
  • 十进制转十六进制
  • 十六进制转十进制
  • 二进制转十六进制
  • 十六进制转二进制

我已经有了一个初步而冗长的方法,但我希望找到更有效的方法。


https://stackoverflow.com/q/45667905/3908884 - Meet Doshi
3个回答

81

StringInt都有可以接受radix(进制)的初始化器。结合使用这些初始化器,您可以实现所有的转换:

// Decimal to binary
let d1 = 21
let b1 = String(d1, radix: 2)
print(b1) // "10101"

// Binary to decimal
let b2 = "10110"
let d2 = Int(b2, radix: 2)!
print(d2) // 22

// Decimal to hexadecimal
let d3 = 61
let h1 = String(d3, radix: 16)
print(h1) // "3d"

// Hexadecimal to decimal
let h2 = "a3"
let d4 = Int(h2, radix: 16)!
print(d4) // 163

// Binary to hexadecimal
let b3 = "10101011"
let h3 = String(Int(b3, radix: 2)!, radix: 16)
print(h3) // "ab"

// Hexadecimal to binary
let h4 = "face"
let b4 = String(Int(h4, radix: 16)!, radix: 2)
print(b4) // "1111101011001110"

@vacawama,如果十六进制值有32个字符会怎么样?我正在尝试将一个由数据库生成的32位字符GUID转换为整数.. - rustyMagnet
@rustyMagnet,32个十六进制字符表示一个128位整数。你会用它做什么? - vacawama
2
@rustyMagnet:你可能想将其转换为UUID,这是Swift(和Java)中GUID的等效物。 - RenniePet
请问您能否提供一个将有符号整数(例如:-52)转换为二进制和十六进制的示例呢?@vacawama - H4Hugo
1
@H4Hugo,String(UInt64(bitPattern: -52), radix: 2)String(UInt64(bitPattern: -52), radix: 16) - vacawama
显示剩余6条评论

3

Swift Converter 2, 8, 10, 16

这是一个使用一些整数和字符串来转换不同系统的工具。

Int 用于处理十进制数,
String 用于处理其他类型的数。

将系统的字符串表示转换为十进制数,以及将十进制数转换为字符串表示是安全的。

String -> Int -> String

这里有一些关于 IT 技术的示例:

binary(2) - 0b
octal(8) - 0o
decimal(10)
hexadecimal(16) - 0x

extension Int {
    
    //From Decimal
    //10 -> 2
    func decToBinString() -> String {
        let result = createString(radix: 2)
        return result
    }
    
    //10 -> 8
    func decToOctString() -> String {
//        let result = decToOctStringFormat()
        let result = createString(radix: 8)
        
        return result
    }
    
    //10 -> 16
    func decToHexString() -> String {
//        let result = decToHexStringFormat()
        let result = createString(radix: 16)
        return result
    }
    
    //10 -> 8
    func decToOctStringFormat(minLength: Int = 0) -> String {

        return createString(minLength: minLength, system: "O")
    }

    //10 -> 16
    func decToHexStringFormat(minLength: Int = 0) -> String {

        return createString(minLength: minLength, system: "X")
    }
    
    fileprivate  func createString(radix: Int) -> String {
        return String(self, radix: radix, uppercase: true)
    }
    
    fileprivate func createString(minLength: Int = 0, system: String) -> String {
        //0 - fill empty space by 0
        //minLength - min count of chars
        //system - system number
        return String(format:"%0\(minLength)\(system)", self)
    }
}

extension String {
    
    //To Decimal
    //2 -> 10
    func binToDec() -> Int {
        return createInt(radix: 2)
    }
    
    //8 -> 10
    func octToDec() -> Int {
        return createInt(radix: 8)
    }
    
    //16 -> 10
    func hexToDec() -> Int {
        return createInt(radix: 16)
    }
    
    //Others
    //2 -> 8
    func binToOct() -> String {
        return self.binToDec().decToOctString()
    }
    
    //2 -> 16
    func binToHex() -> String {
        return self.binToDec().decToHexString()
    }
    
    //8 -> 16
    func octToHex() -> String {
        return self.octToDec().decToHexString()
    }
    
    //16 -> 8
    func hexToOct() -> String {
        return self.hexToDec().decToOctString()
    }
    
    //16 -> 2
    func hexToBin() -> String {
        return self.hexToDec().decToBinString()
    }
    
    //8 -> 2
    func octToBin() -> String {
        return self.octToDec().decToBinString()
    }

    //Additional
    //16 -> 2
    func hexToBinStringFormat(minLength: Int = 0) -> String {
        
        return hexToBin().pad(minLength: minLength)
    }
    
    fileprivate func pad(minLength: Int) -> String {
        let padCount = minLength - self.count
        
        guard padCount > 0 else {
            return self
        }

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

    fileprivate func createInt(radix: Int) -> Int {
        return Int(self, radix: radix)!
    }
    
}

测试:

func testConverter() {
    let decInt = 13511
    let binStr = "11010011000111"
    let octStr = "32307"
    let hexStr = "34C7"
    
    //From Decimal
    //10 -> 2
    XCTAssertEqual(binStr, decInt.decToBinString())
    //10 -> 8
    XCTAssertEqual(octStr, decInt.decToOctString())
    //10 -> 16
    XCTAssertEqual(hexStr, decInt.decToHexString())
    
    //To Decimal
    //2 -> 10
    XCTAssertEqual(decInt, binStr.binToDec())
    //8 -> 10
    XCTAssertEqual(decInt, octStr.octToDec())
    //16 -> 10
    XCTAssertEqual(decInt, hexStr.hexToDec())
    
    //Others
    //2 -> 8
    XCTAssertEqual(octStr, binStr.binToOct())
    //2 -> 16
    XCTAssertEqual(hexStr, binStr.binToHex())
    //8 -> 16
    XCTAssertEqual(hexStr, octStr.octToHex())
    //16 -> 8
    XCTAssertEqual(octStr, hexStr.hexToOct())
    //16 -> 2
    XCTAssertEqual(binStr, hexStr.hexToBin())
    //8 -> 2
    XCTAssertEqual(binStr, octStr.octToBin())

    //String format feature
    //10 -> 8
    XCTAssertEqual("017", (15).decToOctStringFormat(minLength: 3))
    //10 -> 16
    XCTAssertEqual("00F", (15).decToHexStringFormat(minLength: 3))
    //16 -> 2
    XCTAssertEqual("0011010011000111", hexStr.hexToBinStringFormat(minLength: 16))
    
}

0

从十进制到二进制

extension Int {
    //10 -> "2"
    func decToBinString() -> String {
        return String(self, radix: 2, uppercase: true)
    }
}

extension String {
    //"2" -> 10
    func binToDec() -> Int {
        return Int(self, radix: 2)!
    }
}

那个在 String 扩展中强制解包的操作非常危险,因为它可能会导致应用崩溃。最好让该方法返回一个可选类型,这样调用者在编译期间就可以知道它是否可能失败,而不是在运行时崩溃。 - Cristik

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接