如何将非常大的数字转换为十六进制?
例如,647751843213568900000 的十六进制为 0x231d5cd577654ceab3。我可以轻松地从十六进制变为两倍:
let hex: Double = 0x231d5cd577654ceab3
但是我无法弄清楚如何从 Double 返回到 hex。我错过了什么?
以下不起作用,因为它在存储为“Int”时会溢出:
let hexConverted = String(647751843213568900000, radix: 16)
最佳答案
基本算法(Swift 5)如下:
func representationOf<T: FixedWidthInteger>(_ number: T, base: T) -> String {
var buffer: [Int] = []
var n = number
while n > 0 {
buffer.append(Int(n % base))
n /= base
}
return buffer
.reversed()
.map { String($0, radix: Int(base)) }
.joined()
}
print(representationOf(647751843213568900, base: 16))
当然,这是String(_:radix:)
做的,我们不用自己实现。
您真正的问题不是编码,而是大整数的表示。
已经有多种实现,例如 https://github.com/mkrd/Swift-Big-Integer .其中一些已经具有十六进制编码的功能。
在 Swift 4 中,可以声明你自己的更高 IntXXX
的实现(符合 FixedWidthInteger
),问题会变得更容易一些:罢工>
typealias Int128 = DoubleWidth<Int64>
typealias Int256 = DoubleWidth<Int128>
let longNumber = Int256("231d5cd577654ceab3", radix: 16)!
print(longNumber)
print(String(longNumber, radix: 16))
但不幸的是,DoubleWidth
尚未在 Xcode 9 Beta 4 中实现。
对于某些值,您还可以使用 Decimal
类型。使用上面写的算法:
extension Decimal {
func rounded(mode: NSDecimalNumber.RoundingMode) -> Decimal {
var this = self
var result = Decimal()
NSDecimalRound(&result, &this, 0, mode)
return result
}
func integerDivisionBy(_ operand: Decimal) -> Decimal{
let result = (self / operand)
return result.rounded(mode: result < 0 ? .up : .down)
}
func truncatingRemainder(dividingBy operand: Decimal) -> Decimal {
return self - self.integerDivisionBy(operand) * operand
}
}
extension Decimal {
init(_ string: String, base: Int) {
var decimal: Decimal = 0
let digits = Array(string)
.map { String($0) }
.map { Int($0, radix: base)! }
for digit in digits {
decimal *= Decimal(base)
decimal += Decimal(digit)
}
self.init(string: decimal.description)!
}
}
func representationOf(_ number: Decimal, base: Decimal) -> String {
var buffer: [Int] = []
var n = number
while n > 0 {
buffer.append((n.truncatingRemainder(dividingBy: base) as NSDecimalNumber).intValue)
n = n.integerDivisionBy(base)
}
return buffer
.reversed()
.map { String($0, radix: (base as NSDecimalNumber).intValue ) }
.joined()
}
let number = Decimal("231d5cd577654ceab3", base: 16)
print(number) // 647751843213568961203
print(representationOf(number, base: 16)) // 231d5cd577654ceab3
请注意当转换为 Double
时您的值是如何被截断的。
关于swift - 在 Swift 中将 double 转换为十六进制表示法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45057412/