Signed Rotation

Started by
9 comments, last by myvraccount 8 years, 4 months ago

Does anyone know how I can rotate the bits on a signed integer in C#? I don't want to use the carry bit though.

Advertisement
Disclaimer: I don't know any C#, but I still think I can help.

Cast to unsigned int, then use (value << count) | (value >> (32 - count)), then cast back to signed int.

I'm curious though: Why do you want to rotate the bits of a signed integer? It doesn't seem like the most natural operation...

Wouldn't the type conversion mess up the data at all? For example, suppose I had a negative number, and when I convert it into a uint, it will become 0, won't it?

Well let's say I have my reasons but frankly they're hard to explain, with a whole lot of technical junk and honestly I'm in a hurry, but thanks.

Wouldn't the type conversion mess up the data at all? For example, suppose I had a negative number, and when I convert it into a uint, it will become 0, won't it?

Well let's say I have my reasons but frankly they're hard to explain, with a whole lot of technical junk and honestly I'm in a hurry, but thanks.


No, casting will probably preserve the bit pattern, and reinterpret the number by taking the most-significant bit to mean +2^31 instead of -2^31.

See the section "Integral conversions" in this page: https://msdn.microsoft.com/en-us/library/aetzh118.aspx

Wouldn't the type conversion mess up the data at all? For example, suppose I had a negative number, and when I convert it into a uint, it will become 0, won't it?

Well let's say I have my reasons but frankly they're hard to explain, with a whole lot of technical junk and honestly I'm in a hurry, but thanks.


Casting between signed and unsigned just changes the interpretation of the underlying data, no actualy changes to the data happens. Signed numbers use 2s complement so negative numbers in signed turn into a large positive number which depends on how many bits are in the number.

EDIT: Alvaro beat me to it
My current game project Platform RPG
Conveniently, signed-to-unsigned conversions do not clamp the old value to the new range of supported values, but just reinterpret the data as an unsigned integer. From MSDN:

Objects of signed integral types can be converted to corresponding unsigned types. When these conversions occur, the actual bit pattern does not change; however, the interpretation of the data changes.


Further, I'm pretty sure that the integer data sizes and bit patterns of .NET integers are well defined (in contrast to languages like C++ where 32-bit width or 2's complement representation of signed integers can't be relied upon portably). So if you you really want to preserve that sign bit, and rotate everything else, you can do so (untested):
int rotated = (value & 0x80000000) | ((value << count) | (value >> (31 - count))) & 0x7FFFFFFF;

EDIT: Alvaro beat me to it

EDIT: Alvaro and HappyCoder both beat me to it. :-)
"We should have a great fewer disputes in the world if words were taken for what they are, the signs of our ideas only, and not for things themselves." - John Locke

Why the two constants? Also, I don't remember which happens first, the | or the &? I generally put them in parentheses to avoid confusion so I don't really have to know. But it's the... &, right?

C# operator precedence
Yes, first priority goes to &. However you can use parentheses to give priority and to better visualize the order of priority.

If you mean the constant 0x80000000, this is the maximum value that can have a signed int. You need it to do the bitwise & with the value chosen by you, so you "cut" the value on the range of unsigned.

The purpose of the first constant and the & with value is to get the sign bit and nothing else (every other bit is forced to be 0). The second constant does the opposite; it makes sure that the half of the expression after the | does not contain the sign bit (that bit is always forced to 0). Then when the two halves are or-ed together, their bits are guaranteed to not overlap or interfere. So we're basically merging the original sign bit with the newly rotated non-sign bits.

I forgot to mention it yesterday, but keep in mind that negative numbers are almost always represented using two's complement, which means that simply flipping the sign bit does not simply flip the sign of the number while otherwise leaving its value unchanged. Depending on how you use the results of a sign-preserving rotation, this might fail to produce the values you are looking for.

"We should have a great fewer disputes in the world if words were taken for what they are, the signs of our ideas only, and not for things themselves." - John Locke

This topic is closed to new replies.

Advertisement