I believe your expression is incorrect when considering order priority in C #. Your code, I believe, converts your long to ulong , and then back to long , and then switches. I assume that you intend to shift to ulong .
From C # Specification Β§7.2.1 , Unary (or, in your case, the casting operation) takes precedence over the shift. So your code is:
long l = (long) ((ulong) number) >> 2;
will be interpreted as:
ulong ulongNumber = (ulong)number; long longNumber = (long)ulongNumber; long shiftedlongNumber = longNumber >> 2;
Given a number as -2147483648L , this gives 536870912 .
Conversion wrap and offset in brackets:
long l = (long) (((ulong) number) >> 2);
It produces logic that can be rewritten as:
ulong ulongNumber = (ulong)number; ulong shiftedulongNumber = ulongNumber >> 2; long longShiftedNumber = (long)shiftedulongNumber;
Which value of number like -2147483648L , it gives 4611686017890516992 .
EDIT: Please note that given these ordering rules, my answer has an extra set of brackets that are not needed. The correct expression can be written as:
long l = (long) ((ulong) number >> 2);
source share