@npalardy I think I might have cracked it!!!
Full disclosure: I posted this on the main Xojo forum too - I had got some help from people there also (not to mention @npalardy posting in both places - superstar!).
The issue is that Java assumes that all numeric literals are Int32
unless specifically stipulated by suffixing the literal with L
. since Xojo infers that numeric literals are Int64
by default, we begin to see the issue.
The solution is that we 3 need methods. One to replicate Java’s >>
signed right shift operator:
Function RightShift(v As Int64, s As Integer) as Int64
If v >= 0 Then
Return Bitwise.ShiftRight(v, s)
Else
If s = 1 Then
Return Bitwise.BitOr(&h8000000000000000, Bitwise.ShiftRight(v, s))
End
Return Bitwise.BitOr(Bitwise.ShiftLeft(-1, 64 - s), Bitwise.ShiftRight(v, s))
End
End Function
And we need two methods to handle Java’s >>>
unsigned right shift operator because how Java handles them depends on whether the left hand operand is an int
( Int32
) or a long
( Int64
).
To pass an Int32
:
Function RightShiftU32(v As Int32, s As Integer) As Int32
Return Bitwise.ShiftRight(v, s, 32)
End Function
To pass an Int64
:
Function RightShiftU64(value As Int64, shift As Integer) As Int64
Return Bitwise.ShiftRight(value, shift, 64)
End Function
Int4 >> x
Proof:
///
' Tests long = int >> x
///
// Values that fit into an Int32.
Var a As Int64 = MathsKit.RightShift(-2, 1)
Var b As Int64 = MathsKit.RightShift(0, 1)
Var c As Int64 = MathsKit.RightShift(-1, 1)
Var d As Int64 = MathsKit.RightShift(1, 1)
Var e As Int64 = MathsKit.RightShift(100, 1)
Var f As Int64 = MathsKit.RightShift(-2147483648, 1)
Var g As Int64 = MathsKit.RightShift(2147483647, 1)
Var h As Int64 = MathsKit.RightShift(2147483647, 5)
Var i As Int64 = MathsKit.RightShift(-1, 30)
Assert.AreEqual(-1, a)
Assert.AreEqual(0, b)
Assert.AreEqual(-1, c)
Assert.AreEqual(0, d)
Assert.AreEqual(50, e)
Assert.AreEqual(-1073741824, f)
Assert.AreEqual(1073741823, g)
Assert.AreEqual(67108863, h)
Assert.AreEqual(-1, i)
// Use values that would only fit in an Int64.
Var j As Int64 = MathsKit.RightShift(2147483999, 1)
Var k As Int64 = MathsKit.RightShift(-2147483999, 30)
Assert.AreEqual(1073741999, j)
Assert.AreEqual(-3, k)
Int32 >>> x
Proof
///
' Tests long = int >>> x
///
Var a As Int64 = MathsKit.RightShiftU32(-2, 1) ' -2 >>> 1
Var b As Int64 = MathsKit.RightShiftU32(0, 1) ' 0 >>> 1
Var c As Int64 = MathsKit.RightShiftU32(-1, 1) ' -1 >>> 1
Var d As Int64 = MathsKit.RightShiftU32(1, 1) ' 1 >>> 1
Var e As Int64 = MathsKit.RightShiftU32(100, 1) ' 100 >>> 1
Var f As Int64 = MathsKit.RightShiftU32(-2147483648, 1) ' -2147483648, >>> 1
Var g As Int64 = MathsKit.RightShiftU32(2147483647, 1) ' 2147483647 >>> 1
Assert.AreEqual(2147483647, a)
Assert.AreEqual(0, b)
Assert.AreEqual(2147483647, c)
Assert.AreEqual(0, d)
Assert.AreEqual(50, e)
Assert.AreEqual(1073741824, f)
Assert.AreEqual(1073741823, g)
Int64 >>> x
Proof:
///
' Tests long = long >>> x
///
Var a As Int64 = MathsKit.RightShiftU64(-2, 1) ' -2 >>> 1
Var b As Int64 = MathsKit.RightShiftU64(0, 1) ' 0 >>> 1
Var c As Int64 = MathsKit.RightShiftU64(-1, 1) ' -1 >>> 1
Var d As Int64 = MathsKit.RightShiftU64(1, 1) ' 1 >>> 1
Var e As Int64 = MathsKit.RightShiftU64(100, 1) ' 100 >>> 1
Var f As Int64 = MathsKit.RightShiftU64(-2147483648, 1) ' -2147483648, >>> 1
Var g As Int64 = MathsKit.RightShiftU64(2147483647, 1) ' 2147483647 >>> 1
Var h As Int64 = MathsKit.RightShiftU64(2147483999, 1) ' 2147483999 >>> 1
Assert.AreEqual(9223372036854775807, a)
Assert.AreEqual(0, b)
Assert.AreEqual(9223372036854775807, c)
Assert.AreEqual(0, d)
Assert.AreEqual(50, e)
Assert.AreEqual(9223372035781033984, f)
Assert.AreEqual(1073741823, g)
Assert.AreEqual(1073741999, h)
This is when Norman finds a bug and posts a more elegant solution in like 2 minutes time!