gpt4 book ai didi

swift - Swift 中的无符号右移运算符 '>>>'

转载 作者:搜寻专家 更新时间:2023-10-31 22:01:53 24 4
gpt4 key购买 nike

您将如何在 Swift 中实现与 Java 的无符号右移运算符等效的运算符?

根据 Java's documentation ,无符号右移运算符“>>>”将一个零移到最左边的位置,而“>>”之后的最左边位置取决于符号扩展。

例如,

    long s1 = (-7L >>> 16); // result is 281474976710655L
long s2 = (-7L >> 16); // result is -1

为了在 Swift 中实现这一点,我会通过类似的方式获取除符号位之外的所有位,

    let lsb = Int64.max + negativeNumber + 1

注意数字必须是负数!如果您溢出移位运算符,应用程序会因 EXC_BAD_INSTRUCTION 崩溃,这不是很好...另外,我是故意使用 Int64 的。因为没有更大的数据类型,所以执行类似 (1 << 63) 的操作会溢出 Int64 并导致崩溃。因此,我没有在更大的数据类型中执行 ((1 << 63) - 1 + negativeNumber),而是将其写为 Int64.max + negativeNumber - 1。

然后,用正常的逻辑移位对该正数进行移位,并对符号后第一个左位中的符号位进行或运算。

    let shifted = (lsb >> bits) | 0x4000000000000000

但是,这并没有给我预期的结果,

    ((Int64.max - 7 + 1) >> 16) | 0x4000000000000000 // = 4611826755915743231

不知道我做错了什么......另外,是否可以将此运算符命名为“>>>”并扩展 Int64?

编辑:在下面添加来自 OOper 的解决方案,

infix operator >>> : BitwiseShiftPrecedence

func >>> (lhs: Int64, rhs: Int64) -> Int64 {
return Int64(bitPattern: UInt64(bitPattern: lhs) >> UInt64(rhs))
}

我在 Swift 中实现了 Java Random 类,它还涉及将 64 位整数截断为 32 位整数。感谢 OOper,我刚刚意识到我可以使用 truncatingBitPattern 初始化程序来避免溢出异常。 here 中描述的“下一步”功能在 Swift 中变成这样,

var seed: Int64 = 0
private func next(_ bits: Int32) -> Int32 {
seed = (seed &* 0x5DEECE66D &+ 0xB) & ((1 << 48) - 1)
let shifted : Int64 = seed >>> (48 - Int64(bits))
return Int32(truncatingBitPattern: shifted)
}

最佳答案

一个确定的方法是使用无符号整数类型的无符号移位操作:

infix operator >>> : BitwiseShiftPrecedence

func >>> (lhs: Int64, rhs: Int64) -> Int64 {
return Int64(bitPattern: UInt64(bitPattern: lhs) >> UInt64(rhs))
}

print(-7 >>> 16) //->281474976710655

(使用 -7 来测试位计数 16 似乎不是一个很好的例子,它会丢失所有有效位并右移 16 位。)

如果您想按照自己的方式进行,按位或运算丢失的符号位不能是常量 0x4000000000000000。当位计数 == 0 时,它需要是 0x8000_0000_0000_0000(此常量在 Swift Int64 中溢出),并且需要用相同的位进行逻辑移位。

所以,你需要这样写:

infix operator >>>> : BitwiseShiftPrecedence

func >>>> (lhs: Int64, rhs: Int64) -> Int64 {
if lhs >= 0 {
return lhs >> rhs
} else {
return (Int64.max + lhs + 1) >> rhs | (1 << (63-rhs))
}
}

print(-7 >>>> 16) //->281474976710655

当您需要无符号移位操作时,使用无符号整数类型似乎要容易得多。

关于swift - Swift 中的无符号右移运算符 '>>>',我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41202147/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com