当前位置: 首页 > 知识库问答 >
问题:

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

吕向荣
2023-03-14
    long s1 = (-7L >>> 16); // result is 281474976710655L
    long s2 = (-7L >> 16); // result is -1

为了在Swift中实现这一点,我将通过执行以下操作来获取除符号位以外的所有位,

    let lsb = Int64.max + negativeNumber + 1

注意数字必须是负数!如果shift操作符溢出,应用程序就会随着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

编辑:在这里添加下面OOper的解决方案,

infix operator >>> : BitwiseShiftPrecedence

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

我在Swift中实现了Java Random类,它还涉及到将64位ints截断为32位。多亏了OOper,我才意识到可以使用truncatingBitPattern初始化器来避免溢出异常。这里描述的函数'next'在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)
}

共有1个答案

陈胤
2023-03-14

一种可靠的方法是使用无符号整数类型的无符号移位操作:

infix operator >>> : BitwiseShiftPrecedence

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

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

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

如果要以自己的方式执行,按位的缺失符号位不能是常量0x40000000000000000。当位计数==0时,它需要为0x8000_0000_0000_0000(该常量在Swiftint64中溢出),并且需要用相同的位进行逻辑移位。

因此,您需要编写如下内容:

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

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

 类似资料:
  • 问题内容: 无符号右移运算符在最左边插入0。所以当我这样做 输出 因此,它将在最左边的位中插入0。 输出 不应该是0吗? 问题答案: 参见http://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.19 如果左侧操作数的提升类型为int,则仅将右侧操作数的最低5位用作移位距离。就像右侧操作数受到掩码值0x1f(0b1111

  • 问题内容: 如何在SQL Server中编写无符号右移运算符?表情就像 这是例如 -5381 >>> 0 = 4294961915 问题答案: T-SQL没有移位运算符,因此您必须自己实现。这里有一个按位移位的实现:http : //dataeducation.com/bitmask- handling-part-4-left-shift-and-right-shift/ 您必须将整数强制转换为v

  • 问题内容: 我了解Java中的无符号右移运算符“ >>>”是什么,但是为什么我们需要它,为什么我们不需要相应的无符号左移运算符? 问题答案: 该运营商允许你将和为32位和64位 无符号 整型,这是从Java语言缺少的。 当您移动不代表数值的内容时,这很有用。例如,您可以使用32位s 表示黑白位图图像,其中每个位图在屏幕上编码32个像素。如果需要将图像向右滚动,则希望将an左侧的位变为零,以便可以轻

  • 简单的问题:为什么如果我在Java中对字节变量应用无符号右移(也是短的),它就像int一样威胁它: 控制台输出:

  • 有符号和无符号变量在按位运算上有区别吗?< br >例如,在处理无符号数字时:< br> 将得到00000101。 但当处理带符号的数字时会发生什么?

  • 问题内容: 当遇到按位移位运算符时,我遇到了一个有趣的场景。如果第二个操作数为负,按位移位运算如何工作?。 即,<< << b,“ <<”将a中的位模式向左移动b位。但是,如果b为负数,在运行时是否应该出错? 我能够成功运行以下代码,但我不知道它是如何工作的? 输入项 结果 “ a”的ASCII码为97。有人可以帮助我了解其工作原理吗? 问题答案: 但是,如果b为负数,在运行时是否应该出错? 不符