What is the equivalent (in C#) of Java's >>> operator?
(Just to clarify, I'm not referring to the >> and << operators.)
Edit: The Unsigned right-shift operator >>> is now also available in C# 11 and later.
For earlier C# versions, you can use unsigned integer types, and then the << and >> do what you expect. The MSDN documentation on shift operators gives you the details.
Since Java doesn't support unsigned integers (apart from char), this additional operator became necessary.
Java doesn't have an unsigned left shift (<<<), but either way, you can just cast to uint and shfit from there.
E.g.
(int)((uint)foo >> 2); // temporarily cast to uint, shift, then cast back to int
Upon reading this, I hope my conclusion of use as follows is correct.
If not, insights appreciated.
Java
i >>>= 1;
C#:
i = (int)((uint)i >> 1);
n >>> s in Java is equivalent to TripleShift(n,s) where:
private static long TripleShift(long n, int s)
{
if (n >= 0)
return n >> s;
return (n >> s) + (2 << ~s);
}
There is no >>> operator in C#. But you can convert your value like int,long,Int16,Int32,Int64 to unsigned uint, ulong, UInt16,UInt32,UInt64 etc.
Here is the example.
private long getUnsignedRightShift(long value,int s)
{
return (long)((ulong)value >> s);
}
C# 11 and later supports >>> Unsigned right shift operator
https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/operators/bitwise-and-shift-operators#unsigned-right-shift-operator-
For my VB.Net folks
The suggested answers above will give you overflow exceptions with Option Strict ON
Try this for example -100 >>> 2 with above solutions:
The following code works always for >>>
Function RShift3(ByVal a As Long, ByVal n As Integer) As Long
If a >= 0 Then
Return a >> n
Else
Return (a >> n) + (2 << (Not n))
End If
End Function
Related
I'm trying to implement a function that performs a circular rotation of a byte to the left and to the right.
I wrote the same code for both operations. For example, if you are rotating left 1010 becomes 0101. Is this right?
unsigned char rotl(unsigned char c) {
int w;
unsigned char s = c;
for (w = 7; w >= 0; w--) {
int b = (int)getBit(c, w);//
if (b == 0) {
s = clearBit(s, 7 - w);
} else if (b == 1) {
s = setBit(s, 7 - w);
}
}
return s;
}
unsigned char getBit(unsigned char c, int n) {
return c = (c & (1 << n)) >> n;
}
unsigned char setBit(unsigned char c, int n) {
return c = c | (1 << n);
}
unsigned char clearBit(unsigned char c, int n) {
return c = c &(~(1 << n));
}
There is no rotation operator in C, but if you write:
unsigned char rotl(unsigned char c)
{
return (c << 1) | (c >> 7);
}
then, according to this: http://www.linux-kongress.org/2009/slides/compiler_survey_felix_von_leitner.pdf (page 56), compilers will figure out what you want to do and perform the rotation it in only one (very fast) instruction.
Reading the answers and comments so far, there seems to be some confusion about what you are trying to accomplish - this may be because of the words you use. In bit manipulation, there are several "standard" things you can do. I will summarize some of these to help clarify different concepts. In all that follows, I will use abcdefgh to denote 8 bits (could be ones or zeros) - and as they move around, the same letter will refer to the same bit (maybe in a different position); if a bit becomes "definitely 0 or 1, I will denote it as such).
1) Bit shifting: This is essentially a "fast multiply or divide by a power of 2". The symbol used is << for "left shift" (multiply) or >> for right shift (divide). Thus
abcdefgh >> 2 = 00abcdef
(equivalent to "divide by four") and
abcdefgh << 3 = abcdefgh000
(equivalent to "multiply by eight" - and assuming there was "space" to shift the abc into; otherwise this might result in an overflow)
2) Bit masking: sometimes you want to set certain bits to zero. You do this by doing an AND operation with a number that has ones where you want to preserve a bit, and zeros where you want to clear a bit.
abcdefgh & 01011010 = 0b0de0g0
Or if you want to make sure certain bits are one, you use the OR operation:
abcdefgh | 01011010 = a1c11f1h
3) Circular shift: this is a bit trickier - there are instances where you want to "move bits around", with the ones that "fall off at one end" re-appearing at the other end. There is no symbol for this in C, and no "quick instruction" (although most processors have a built-in instruction which assembler code can take advantage of for FFT calculations and such). If you want to do a "left circular shift" by three positions:
circshift(abcdefgh, 3) = defghabc
(note: there is no circshift function in the standard C libraries, although it exists in other languages - e.g. Matlab). By the same token a "right shift" would be
circshift(abcdefgh, -2) = ghabcdef
4) Bit reversal: Sometimes you need to reverse the bits in a number. When reversing the bits, there is no "left" or "right" - reversed is reversed:
reverse(abcdefgh) = hgfedcba
Again, there isn't actually a "reverse" function in standard C libraries.
Now, let's take a look at some tricks for implementing these last two functions (circshift and reverse) in C. There are entire websites devoted to "clever ways to manipulate bits" - see for example this excellent one. for a wonderful collection of "bit hacks", although some of these may be a little advanced...
unsigned char circshift(unsigned char x, int n) {
return (x << n) | (x >> (8 - n));
}
This uses two tricks from the above: shifting bits, and using the OR operation to set bits to specific values. Let's look at how it works, for n = 3 (note - I am ignoring bits above the 8th bit since the return type of the function is unsigned char):
(abcdefgh << 3) = defgh000
(abcdefgh >> (8 - 3)) = 00000abc
Taking the bitwise OR of these two gives
defgh000 | 00000abc = defghabc
Which is exactly the result we wanted. Note also that a << n is the same as a >> (-n); in other words, right shifting by a negative number is the same as left shifting by a positive number, and vice versa.
Now let's look at the reverse function. There are "fast ways" and "slow ways" to do this. Your code above gave a "very slow" way - let me show you a "very fast" way, assuming that your compiler allows the use of 64 bit (long long) integers.
unsigned char reverse(unsigned char b) {
return (b * 0x0202020202ULL & 0x010884422010ULL) % 1023;
}
You may ask yourself "what just happened"??? Let me show you:
b = abcdefgh
* 0x0000000202020202 = 00000000 00000000 0000000a bcdefgha bcdefgha bcdefgha bcdefgha bcdefgh0
& 0x0000010884422010 = 00000000 00000000 00000001 00001000 10000100 01000010 00100000 00010000
= 00000000 00000000 0000000a 0000f000 b0000g00 0c0000h0 00d00000 000e0000
Note that we now have all the bits exactly once - they are just in a rather strange pattern. The modulo 1023 division "collapses" the bits of interest on top of each other - it's like magic, and I can't explain it. The result is indeed
hgfedcba
A slightly less obscure way to achieve the same thing (less efficient, but works for larger numbers quite efficiently) recognizes that if you swap adjacent bits , then adjacent bit pairs, then adjacent nibbles (4 bit groups), etc - you end up with a complete bit reversal. In that case, a byte reversal becomes
unsigned char bytereverse(unsigned char b) {
b = (b & 0x55) << 1 | (b & 0xAA) >> 1; // swap adjacent bits
b = (b & 0x33) << 2 | (b & 0xCC) >> 2; // swap adjacent pairs
b = (b & 0x0F) << 4 | (b & 0xF0) >> 4; // swap nibbles
return b;
}
In this case the following happens to byte b = abcdefgh:
b & 0x55 = abcdefgh & 01010101 = 0b0d0f0h << 1 = b0d0f0h0
b & 0xAA = abcdefgh & 10101010 = a0c0e0g0 >> 1 = 0a0c0e0g
OR these two to get badcfehg
Next line:
b & 0x33 = badcfehg & 00110011 = 00dc00hg << 2 = dc00hg00
b & 0xCC = badcfehg & 11001100 = ba00fe00 >> 2 = 00ba00fe
OR these to get dcbahgfe
last line:
b & 0x0F = dcbahgfe & 00001111 = 0000hgfe << 4 = hgfe0000
b & 0xF0 = dcbahgfe & 11110000 = dcba0000 >> 4 = 0000dcba
OR these to get hgfedcba
Which is the reversed byte you were after. It should be easy to see how just a couple more lines (similar to the above) get you to a reversed integer (32 bits). As the size of the number increases, this trick becomes more and more efficient, comparatively.
I trust that the answer you were looking for is "somewhere" in the above. If nothing else I hope you have a clearer understanding of the possibilities of bit manipulation in C.
If, as according to your comments, you want to shift one bit exactly, then one easy way to accomplish that would be this:
unsigned char rotl(unsigned char c)
{
return((c << 1) | (c >> 7));
}
What your code does is reversing the bits; not rotating them. For instance, it would make 10111001 into 10011101, not 01110011.
C# provides the method Convert.ToUInt16("FFFF", 16)/Convert.ToInt16("FFFF", 16) to convert hex strings into unsigned and signed 16 bit integer. These methods works fine for 16/32 bit values but not so for 12 bit values.
I would like to convert 3 char long hex string to signed integer. How could I do it? I would prefer a solution that could take the number of character as parameter to decide signed values.
Convert(string hexString, int fromBase, int size)
Convert("FFF", 16, 12) return -1.
Convert("FFFF", 16, 16) return -1.
Convert("FFF", 16, 16) return 4095.
The easiest way I can think of converting 12 bit signed hex to a signed integer is as follows:
string value = "FFF";
int convertedValue = (Convert.ToInt32(value, 16) << 20) >> 20; // -1
The idea is to shift the result as far left as possible so that the negative bits line up, then shift right again to the original position. This works because a "signed shift right" operation keeps the negative bit in place.
You can generalize this into a method as follows:
int Convert(string value, int fromBase, int bits)
{
int bitsToShift = 32 - bits;
return (Convert.ToInt32(value, fromBase) << bitsToShift) >> bitsToShift;
}
You can cast the result to a short if you want a 16 bit value when working with 12 bit hex strings. Performance of this method will be the same as a 16 bit version because bit shift operators on short cast the values to int anyway and this gives you more flexibility to specify more than 16 bits if needed without writing another method.
Ah, you'd like to calculate the Two's Complement for a certain number of bits (12 in your case, but really it should work with anything).
Here's the code in C#, blatantly stolen from the Python example in the wiki article:
int Convert(string hexString, int fromBase, int num_bits)
{
var i = System.Convert.ToUInt16(hexString, fromBase);
var mask = 1 << (num_bits - 1);
return (-(i & mask) + (i & ~mask));
}
Convert("FFF", 16, 12) returns -1
Convert("4095", 10, 12) is also -1 as expected
I am trying to understand why BigInteger is throwing an overflow exception. I tried to visualize this by converting the BigInteger to a byte[] and iteratively incrementing the shift until I see where the exception occurs.
Should I be able to bit-shift >> a byte[], or is C# simply not able to?
Code causing an exception
uint amountToShift2 = 12;
BigInteger num = new BigInteger(-126);
uint compactBitsRepresentation = (uint)(num >> (int)amountToShift2);
Regarding your edited question with:
uint amountToShift2 = 12;
BigInteger num = new BigInteger(-126);
uint compactBitsRepresentation = (uint)(num >> (int)amountToShift2);
The bit shift works OK and produces a BigInteger of value -1 (negative one).
But the conversion to uint throws an exception becauce -1 is outside the range of an uint. The conversion from BigInteger to uint does not "wrap around" modulo 2**32, but simply throws.
You can get around that with:
uint compactBitsRepresentation = (uint)(int)(num >> (int)amountToShift2);
which will not throw in unchecked context (which is the usual context).
There is no >> or << bit-shift operators for byte arrays in C#. You need to write code by hand to do so (pay attention to bits that fall off).
Something tells me that the >> operator won't work with reference types like arrays, rather it works with primitive types.
your ints are actually represented by a series of bytes, so say
int i = 6;
i is represented as
00000000000000000000000000000110
the >> shifts all the bits to the right, changing it to
00000000000000000000000000000011
or 3
If you really need to shift the byte array, it shouldn't be too terribly hard to define your own method to move all the items of the array over 1 slot. It will have O(n) time complexity though.
I'm attempting to convert a pseudo rand function from c++ to c# but it doesnt seem to return the correct values. Its important that i use a consistent set for encryption so i cant just use a random number.
this is the function in c++.
int get_pseudo_rand()
{
return( ((_last_rand = _last_rand * 214013L
+ 2531011L) >> 16) & 0x7fff );
}
and this is my c# alternative
int get_pseudo_rand()
{
return (((_last_rand = (_last_rand * 214013 + 2531011) >> 16) & 0x7fff));
}
I removed the Ls since c#s int data type is 4 bytes like c++ longs whereas c#s longs are 8 bytes.
the first time the function is run from the seed the answer is consistent with the c++ version but then it begins to diverge.
Any ideas?
You have parenthesized the two statements in a different way that changes their meaning. The C++ code updates _last_rand and then right-shifts the result, the C# code performs the right-shift before updating _last_rand. I've lined the statements up below to make the difference more obvious.
C++:
return (((_last_rand = _last_rand * 214013L + 2531011L) >> 16) & 0x7fff);
C#:
return (((_last_rand = (_last_rand * 214013 + 2531011 ) >> 16) & 0x7fff));
The problem is that you have parenthesized differentyl which leads to storing different values in _last_rand... with your code _last_rand stores 28818 after the first run... with the C++ code it stores 1888663550 which is the value BEFORE >> and before &. Thus it startes diverging from second run on...
To achieve the same behaviour as in C++ use in C#
return (((_last_rand = _last_rand * 214013 + 2531011) >> 16) & 0x7fff);
In C++ I have code like this.
static UInt32 rol(UInt32 value, UInt32 bits)
{
bits &= 31;
return ((value << bits) | (value >> (32 - bits)));
}
static UInt32 ror(UInt32 value, UInt32 bits)
{
bits &= 31;
return ((value >> bits) | (value << (32 - bits)));
}
how would it look in C#? I think the same exact way.. only problem
Error 2 Operator '>>' cannot be applied to operands of type 'uint' and 'uint'
Error 3 Operator '>>' cannot be applied to operands of type 'uint' and 'uint'
Error 1 Operator '<<' cannot be applied to operands of type 'uint' and 'uint'
Error 4 Operator '<<' cannot be applied to operands of type 'uint' and 'uint'
You should use int type for the right side variable in shift operators.
You will have to cast the right side of the bitshift operator to int. If you cast like (int)(32 - bits), it should not affect your intended purpose. The right side is just expecting an int, probably because it's simpler that way and highly unlikely you'll ever want to shift more than 2 billion bits.
The right operand must be always type int.
int x << int bits
uint x << int bits
long x << int bits
ulong x << int bits
Add some parentheses and it works:
byte[] bytes = { 1, 2, 4, 8 };
UInt32 crc32 = ((UInt32)msg.Data[3] << 24) +
((UInt32)msg.Data[2] << 16) +
((UInt32)msg.Data[1] << 8) +
msg.Data[0];