0

bitwise 및/또는 BigInt을 사용할 때 발생하는 다음과 같은 문제를 이해하려고합니다. 목표는 두 개의 Long 값을 결합하여 "128 비트 BigInt"값을 얻는 것입니다.scala.math.BigInt 비트 연산을 사용할 때의 제한 사항은 무엇입니까?

val uuid = java.util.UUID.fromString("6fcb514b-b878-4c9d-95b7-8dc3a7ce6fd8") 
val msb = BigInt(uuid.getMostSignificantBits) 
// => 8055621744141552797 
val lsb = BigInt(uuid.getLeastSignificantBits) 
// => -7658496769846775848 

합니다 (UUID 재현 할 수있는 두 Long 값을 제공하는 대신 다른 목적을 제공하지 않습니다, 그래서 당신은 그것을 무시할 수) :

먼저, 두 Long 값을 만들 수 있습니다.

bitwise 또는를 사용하여 lsb으로 병합하기 전에 왼쪽으로 msb 비트를 64 비트 이동하는 것이 좋습니다.

val result = (msb << 64) | lsb 

그러나 결과는 lsb 그 자체입니다. 즉, ((msb << 64) | lsb) == lsbtrue입니다. 그 외에도 ((msb << 64) & lsb) == (msb << 64)true입니다.

왜 그렇습니까?

편집 :

비트 시프트가 작동하는 것 같다, msb << 64의 중간 결과가 127 이진수있다 (아마 앞에 0).

+0

음수 값의 부호 비트가 이월됩니다. 모든 앞선 비트는 OR 연산시 시프트 된 값을 제거합니다. 그것은 2 개의 긍정적 인'Long' 값으로 작동해야합니다. – jwvh

+0

물론 감사합니다. 어떤 이유로 나는 음수의 1을 64 비트를 초과하지 않을 것이다. – fxlae

답변

1

다음은 내가하고있는 것을 얻을 수있는 한 가지 방법입니다.

import java.nio.ByteBuffer 

val uuid = java.util.UUID.fromString("6fcb514b-b878-4c9d-95b7-8dc3a7ce6fd8") 

val bb = ByteBuffer.allocate(16) 
bb.putLong(uuid.getMostSignificantBits) 
bb.putLong(uuid.getLeastSignificantBits) 

val result: BigInt = bb.array.foldLeft(BigInt(0))((bi,b) => (bi << 8)|(0xFF & b)) 
// result = 148599992668788990968304946804723445720 

// proof it works 
println(f"$result%x") // 6fcb514bb8784c9d95b78dc3a7ce6fd8 
+0

감사합니다. 그러나 우리는'ByteBuffer'와'Array [Byte]'를 필요로하기 때문에'BigInt (bb.array)'만 할 수도 있습니다. – fxlae