Быстрые родные функции имеют числа в виде шестнадцатеричных строк
Есть ли какой-либо собственный способ Swift для любого (как минимум целого) числа, чтобы получить его шестнадцатеричное представление в строке? И наоборот. Он не должен использовать Foundation. Например, класс String имеет функцию
func toInt() -> Int?
который преобразует строку, представляющую целое число, в значение Int. Я ищу что-то подобное, используя шестнадцатеричные строки. Я знаю, что это легко реализовать, но если бы у Swift это было, то было бы лучше. В противном случае, если вы уже сделали расширение String и Int для достижения следующего:
let anHex = "0xA0"
if let anInt = anHex.toInt() {
println(anInt) // prints 128
println(anInt.toHexString()) // prints "0xA0"
}
Я знаю, что это не ракетостроение, но в случае, пожалуйста, поделитесь им.
PS: Это похоже на этот вопрос, разница в том, что он был очень связан с базой Foundation, в то время как я не использую его в своем коде (и Я импортирую что-нибудь еще), и сейчас я хотел бы сохранить его таким же образом, а также для учебных целей.
Ответы
Ответ 1
В Swift 2, все целые типы имеют конструктор
init?(_ text: String, radix: Int = default)
так что оба целых
можно использовать шестую строку и шестую строку для целых преобразований
с встроенными методами. Пример:
let num = 1000
let str = String(num, radix: 16)
print(str) // "3e8"
if let num2 = Int(str, radix: 16) {
print(num2) // 1000
}
(Старый ответ для Swift 1:) Преобразование из целого числа в шестую строку можно сделать с помощью
let hex = String(num, radix: 16)
(см., например, Как преобразовать десятичное число в двоичный файл в Swift?). Это не требует импорта любой Framework
и работает с любой базой от 2 до 36.
Преобразование из шестнадцатеричной строки в целое может быть выполнено с помощью BSD
библиотечная функция strtoul()
(сравните Как преобразовать двоичный код в десятичный в Swift?), если вы хотите import Darwin
.
В противном случае (насколько я знаю) нет встроенного метода Swift. Вот расширение
который преобразует строку в число согласно заданной базе:
extension UInt {
init?(_ string: String, radix: UInt) {
let digits = "0123456789abcdefghijklmnopqrstuvwxyz"
var result = UInt(0)
for digit in string.lowercaseString {
if let range = digits.rangeOfString(String(digit)) {
let val = UInt(distance(digits.startIndex, range.startIndex))
if val >= radix {
return nil
}
result = result * radix + val
} else {
return nil
}
}
self = result
}
}
Пример:
let hexString = "A0"
if let num = UInt(hexString, radix: 16) {
println(num)
} else {
println("invalid input")
}
Ответ 2
update: Xcode 7.2 • Swift 2.1.1
extension String {
var drop0xPrefix: String { return hasPrefix("0x") ? String(characters.dropFirst(2)) : self }
var drop0bPrefix: String { return hasPrefix("0b") ? String(characters.dropFirst(2)) : self }
var hexaToDecimal: Int { return Int(drop0xPrefix, radix: 16) ?? 0 }
var hexaToBinaryString: String { return String(hexaToDecimal, radix: 2) }
var decimalToHexaString: String { return String(Int(self) ?? 0, radix: 16) }
var decimalToBinaryString: String { return String(Int(self) ?? 0, radix: 2) }
var binaryToDecimal: Int { return Int(drop0bPrefix, radix: 2) ?? 0 }
var binaryToHexaString: String { return String(binaryToDecimal, radix: 16) }
}
extension Int {
var toBinaryString: String { return String(self, radix: 2) }
var toHexaString: String { return String(self, radix: 16) }
}
Тестирование:
print("7fffffffffffffff".hexaToDecimal) // "9223372036854775807" decimal integer
print("0x7fffffffffffffff".hexaToDecimal) // "9223372036854775807" decimal integer
print("7fffffffffffffff".hexaToBinaryString) // "111111111111111111111111111111111111111111111111111111111111111" binary (String)
print("0x7fffffffffffffff".hexaToBinaryString) // "111111111111111111111111111111111111111111111111111111111111111"
print("255".decimalToHexaString) // "ff" hexa (String)
print("255".decimalToBinaryString) // "11111111" binary (String)
0b11111111
print("11111111".binaryToHexaString) // "ff" hexa (String)
print("0b11111111".binaryToHexaString) // "ff" hexa (String)
print("11111111".binaryToDecimal) // 255 decimal (Int)
print("0b11111111".binaryToDecimal) // 255 decimal (Int)
print(255.toBinaryString) // "11111111" binary (String)
print(255.toHexaString) // "ff" hexadecimal (String)
Ответ 3
Swift 3:
String
до UInt
:
let str = "fcd7d7"
let number = UInt(str, radix: 16)!
print(number)
результат: 16570327
UInt
в hex String
:
let number = UInt(exactly: 16570327)!
let str = String(number, radix: 16, uppercase: false)
print(str)
результат: fcd7d7
Ответ 4
Для Float, если вы хотите, чтобы плавающая точка IEEE754 с HEX
extension Float {
func floatToHex()->String {
return String(self.bitPattern, radix: 16, uppercase: true)
}
}
let f:Float = 3.685746e+19
let hex = f.floatToHex()
print("\(hex)")//5FFFC000
Или, наоборот,
extension String {
func hexToFloat() -> Float {
var toInt = Int32(truncatingBitPattern: strtol(self, nil, 16))
var float:Float32!
memcpy(&float, &toInt, MemoryLayout.size(ofValue: float))
return float
}
}