Java >>> (zero fill right shift) in Xojo

Hello all.

I need to convert this java binary operations to Xojo

n >>> 8 & 0xFF

How to do that? any advice?

Currently, I’m using this function

[code]public function ZeroFillRightShift(a as Int64, n as Integer) as integer
If (n <= 0) Then Return a

dim b as Int64 = &h80000000

Return Bitwise.ShiftRight(a, n) And Bitwise.OnesComplement(Bitwise.ShiftRight(b, n-1))
end function[/code]

based on PHP code

function zrsh($a, $n) { if ($n <= 0) return $a; $b = 0x80000000; return ($a >> $n) & ~($b >> ($n - 1)); }

As long as I understand this correctly…

Xojo’s default is zero-fill shift-right. You’d have to do something special if you wanted to fill with the first bit.

[quote=276500:@Asis Patisahusiwa]Hello all.

I need to convert this java binary operations to Xojo

n >>> 8 & 0xFF

How to do that? any advice?

Currently, I’m using this function

[code]public function ZeroFillRightShift(a as Int64, n as Integer) as integer
If (n <= 0) Then Return a

dim b as Int64 = &h80000000

Return Bitwise.ShiftRight(a, n) And Bitwise.OnesComplement(Bitwise.ShiftRight(b, n-1))
end function[/code]

based on PHP code

function zrsh($a, $n) { if ($n <= 0) return $a; $b = 0x80000000; return ($a >> $n) & ~($b >> ($n - 1)); }[/quote]

That seems wrong

is “zero fill right shift”
has higher precedence than &

Return Bitwise.BitAnd(Bitwise.ShiftRight(a, n) , &hff)

ie/

public class HelloWorld {
    public static void main(String[] args) {
        int n = 0x12ff ;
        System.out.println(n >>> 8 & 0xff); // Display the string.
    }
}

displays 18
0x12FF shifted right 8 = 0x12
0x12 & 0xFF => 0x12

public class HelloWorld {
    public static void main(String[] args) {
        int n = 0xff12ff ;
        System.out.println(n >>> 8 & 0xff); // Display the string.
    }
}

also displays 18

  dim n as int32 = &hff12ff 
  dim i as int32 = Bitwise.ShiftRight(n, 8)
  dim j as int32 = Bitwise.BitAnd(i, &hff)
  
  break

My post was incorrect. Xojo’s default is bit-fill for Int32 unless you specify the number of bits, but zero-fill for Int64 in all cases. With Int32 and In64 variables assigned the value -8000, these are the results of the various operations:

i32:
11111111111111111110000011000000
Bitwise.ShiftRight( i32, 4 )
11111111111111111111111000001100
Bitwise.ShiftRight( i32, 4, 32 )
00001111111111111111111000001100

i64:
1111111111111111111111111111111111111111111111111110000011000000
Bitwise.ShiftRight( i64, 4 )
0000111111111111111111111111111111111111111111111111111000001100
Bitwise.ShiftRight( i64, 4, 64 )
0000111111111111111111111111111111111111111111111111111000001100

the AND &hFF makes the fill irrelevant

Regardless, I submitted Feedback just in case this is a bug.

<https://xojo.com/issue/44557>

Thank you.

I’ve compared the result of this java code and xojo using bitwise.ShiftRight and got the same result. However, I’ll check the issue.

[code]import java.util.Arrays;

public class HelloWorld {
public static void main(String[] args) {

  int k = 5144;
  int m = 39738973;
  int key = 5734;
  
  int n = m - key + 1815549477 ^ 0x6C371625;
  
  int[] data = new int[4];
  
  data[0] = n & 0xFF;
  data[1] = n >>> 8 & 0xFF;
  data[2] = n >>> 16 & 0xFF;
  data[3] = n >>> 24 & 0xFF;
  
  System.out.println(Arrays.toString(data));
    
}

}[/code]

For your use the 0xFF makes it completely irrelevant what the bitshift inserts as the MSB since the FF masks off just the low 8 bits

[quote=276604:@Kem Tekinay]Regardless, I submitted Feedback just in case this is a bug.

<https://xojo.com/issue/44557>[/quote]

Pretty sure it’s not
Will double check with Joe as he’s out sick today

Pretty sure what s going on is

For a 32 bit value doing a shift right

  1. 32 bit value with MSB set gets assigned to 64 bit value for the framework (it IS documented as taking a 64 bit value)
  2. step 1 causes the sign bit to be extended up through the upper 32 bits of the 64 bit value (this is basically required to make sure that a negative 32 bit value remains the same negative 64 bit value)
  3. the shift is done (note MSB of the 32 bit value will whatever the sign bit WAS set to shifted in BUT the MSB of the 64 bit value will get a 0)
  4. the 64 bit values is return and truncated to 32 bits
  5. the MSB of the 32 bit value still has the sign bit set to whatever it was before (if it was 0 its still 0 if it was 1 its still 1)

For a 64 bit value this behaves differently because there is NO sign extension or truncation going on
So the shift right rolls a 0 into the MSB of the 64 bit value

Too many underlying niggly details but that’s what I suspect is going on - and basically “not a bug” IMHO

When you specify the number of bits as “32” it now treats things as 32 bit instead of 64 bit so the MSB of the 32 bit value gets a 0 rolled into the MSB on a shift