你如何将UInt64转换为Int64?

时间:2014-07-02 18:57:26

标签: swift

尝试在Swift中调用dispatch_time正在努力,这就是为什么:

 dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 10 * NSEC_PER_SEC), dispatch_get_main_queue(), {
            doSomething()
            })

导致错误:"无法找到' *'接受提供的参数"。

NSEC_PER_SEC是一个UInt64,所以有时间进行一些实验:

let x:UInt64 = 1000
let m:Int64 = 10 * x

导致与上述相同的错误

let x:UInt64 = 1000
let m:Int64 = 10 * (Int64) x

结果"一行上的连续陈述必须用';'""

分隔
let x:UInt64 = 1000
let m:Int64 = 10 * ((Int64) x)

结果"预期','分离器"

let x:UInt64 = 1000
let m:Int64 = (Int64)10 * (Int64) x

结果"一行上的连续陈述必须用';'""

分隔

等。等。

该死的Swift编译器,我放弃了。如何将UInt64转换为Int64,和/或如何在swift中使用dispatch_time?

6 个答案:

答案 0 :(得分:5)

试试这个:

let x:UInt64 = 1000 // 1,000
let m:Int64 = 10 * Int64(x) // 10,000

甚至:

let x:UInt64 = 1000 // 1,000
let m = 10 * Int64(x) // 10,000
let n = Int64(10 * x) // 10,000
let y = Int64(x) // 1,000, as Int64 (as per @Bill's question)

与其他类型的初始化相比,它并没有那么多......

答案 1 :(得分:4)

你可以"演员"通过初始化具有所需类型的新整数来在不同的整数类型之间:

let uint:UInt64 = 1234
let int:Int64 = Int64(uint)

在您的特定情况下可能不是问题,但值得注意的是,不同的整数类型具有不同的范围,如果您尝试在整数之间进行转换,最终可能会超出范围崩溃不同类型:

let bigUInt:UInt64 = UInt64(Int64.max) - 1      // 9,223,372,036,854,775,806
let bigInt:Int64 = Int64(bigUInt)               // no problem

let biggerUInt:UInt64 = UInt64(Int64.max) + 1   // 9,223,372,036,854,775,808
let biggerInt:Int64 = Int64(biggerUInt)         // crash!

每个整数类型都有.max.min类属性,可用于检查范围:

if (biggerUInt <= UInt64(Int64.max)) {
    let biggerInt:Int64 = Int64(biggerUInt)     // safe!
}

答案 2 :(得分:2)

UInt64投放到Int64是不安全的,因为UInt64的数字可能大于Int64.max,这会导致溢出。

以下是将UInt64转换为Int64的代码段,反之亦然:

// Extension for 64-bit integer signed <-> unsigned conversion

extension Int64 {
    var unsigned: UInt64 {
        let valuePointer = UnsafeMutablePointer<Int64>.allocate(capacity: 1)
        defer {
            valuePointer.deallocate(capacity: 1)
        }

        valuePointer.pointee = self

        return valuePointer.withMemoryRebound(to: UInt64.self, capacity: 1) { $0.pointee }
    }
}

extension UInt64 {
    var signed: Int64 {
        let valuePointer = UnsafeMutablePointer<UInt64>.allocate(capacity: 1)
        defer {
            valuePointer.deallocate(capacity: 1)
        }

        valuePointer.pointee = self

        return valuePointer.withMemoryRebound(to: Int64.self, capacity: 1) { $0.pointee }
    }
}

这简单地将UInt64的二进制数据解释为Int64,即大于Int64.max的数字将为负数,因为64位的最高位的符号位整数。

如果你只想要正整数,只需得到绝对值。

编辑:根据行为,您可以获得绝对值,或者:

if currentValue < 0 {
    return Int64.max + currentValue + 1
} else {
    return currentValue
}

后一个选项类似于剥离符号位。例如:

// Using an 8-bit integer for simplicity

// currentValue
0b1111_1111 // If this is interpreted as Int8, this is -1.

// Strip sign bit
0b0111_1111 // As Int8, this is 127. To get this we can add Int8.max

// Int8.max + currentValue + 1
127 + (-1) + 1 = 127

答案 3 :(得分:2)

要使用Int64的位构建UInt64,请使用此处显示的inithttps://developer.apple.com/reference/swift/int64/1538466-init

let myInt64 = Int64(bitPattern: myUInt64)

答案 4 :(得分:1)

更好的转换解决方案:

UInt64 Int64_2_UInt64(Int64 Value)
{
     return (((UInt64)((UInt32)((UInt64)Value >> 32))) << 32) 
        | (UInt64)((UInt32)((UInt64)Value & 0x0ffffffff));           
}

Int64 UInt64_2_Int64(UInt64 Value)
{
    return (Int64)((((Int64)(UInt32)((UInt64)Value >> 32)) << 32) 
       | (Int64)((UInt32)((UInt64)Value & 0x0ffffffff)));           
}

答案 5 :(得分:0)

Swift 3的简单解决方案是一个内置函数,负责溢出和缓冲区管理。

var a:UInt64 = 1234567890
var b:Int64 = numericCast(a)