SwiftのJavaの符号なし右シフト演算子と同等の機能をどのように実装しますか?Swiftの符号なし右シフト演算子 '>>>'
Java's documentationによれば、符号なし右シフト演算子「>>>」はゼロを左端にシフトし、「>>」の後の最も左の位置は符号拡張に依存する。
ので、例えば、
long s1 = (-7L >>> 16); // result is 281474976710655L
long s2 = (-7L >> 16); // result is -1
スウィフトでこれを実現するために、私は何かなどを行うことによって符号ビットを除くすべてのビットを取ると、
let lsb = Int64.max + negativeNumber + 1
お知らせナンバーこと否定的でなければなりません!シフト演算子をオーバーフローさせた場合、EXC_BAD_INSTRUCTIONによってアプリケーションがクラッシュします。これは非常にうまくありません。 また、Int64を目的に使用しています。より大きいデータ型がないので、(1 < < 63)のようなことを実行するとInt64がオーバーフローし、クラッシュします。だから、より大きなデータ型で((1 < < 63) - 1 +負の数)を書く代わりに、私は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))
}
Iはまた、32ビットに64ビットのint値を切り捨てることを含むスイフトでJavaランダムクラスを実装しました。 OOperのおかげで、私はtruncatingBitPattern初期化子を使ってオーバーフロー例外を避けることができたことに気付きました。関数は、「次」に記載されるようhereこのなりスウィフト、
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)
}
これは完璧です!ありがとう!また、切り捨て時にオーバーフローを避けるために、私はこれを初期化して使うことができます:Int32(truncatingBitPattern :)これを見ていたのは、Javaのドキュメントで指定されているJava Randomを実装していたからです。私は説明にそれを追加します。 – endavid