This question already has answers here:
What does "somevar >> 0" mean?
(3 answers)
Closed 8 years ago.
Yet another question what does this operator do? How would I write that in C#:
data[id] = R >> 0;
data[id + 1] = G >> 0;
data[id + 2] = B >> 0;
I assume you're talking about the >> operator. It's a right shift operator that first (if necessary) converts the left argument to an integer and then shifts right by the indicated number of bits. Shifting by 0 bits leaves the number unchanged, so R >> 0 is a cute way of forcing R to an integer. It works like Math.floor(R) for non-negative values.
In C#, I believe that you can do the same thing with a cast: (int) R, etc.
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.
This question already has answers here:
char + char = int? Why?
(15 answers)
Closed 4 years ago.
This is something they included as part of my course, just wondering why it does this and what they were trying to show with it but can't seem to figure it out. Is it some sort of principle when trying to concatenate chars to numbers?
Am I right in assuming that 'z' is a char because it's in single quotes here?
Is it some sort of error because you shouldn't write stuff like this?
Thanks in advance!
z is char value, char is basically a number. z will be implicitly converted to int (z code is 122), that's why 3 + 'z' + 4 == 129. It will be converted to int because in statement 3 + 'z' 3 is int, so result of addition will be also int.
In C# char is a 16 bit numeric value which represents a unicode character. So in your case z is implicitly evaluated as 122. So 3 + 122 + 4 equals 129.
This question already has answers here:
Why use the Bitwise-Shift operator for values in a C enum definition?
(9 answers)
Closed 6 years ago.
Ok so I am new to C#, and for the life of me I cannot comprehend what exactly the below code (from a legacy project) is supposed to do:
[Flags]
public enum EAccountStatus
{
None = 0,
FreeServiceApproved = 1 << 0,
GovernmentAccount = 1 << 1,
PrivateOrganisationAccount = 1 << 2,
All = 8
}
What exactly does the << operator do here on the enums? Why do we need this?
Behind the scenes, the enumeration is actually an int.
<< is the Bitwise Left Shift Operator
An equivalent way of writing this code is :
[Flags]
public enum EAccountStatus
{
None = 0,
FreeServiceApproved = 1,
GovernmentAccount = 2,
PrivateOrganisationAccount = 4,
All = 8
}
Please note, that this enumeration has the Flag attribute
As stated in the msdn:
Use the FlagsAttribute custom attribute for an enumeration only if a
bitwise operation (AND, OR, EXCLUSIVE OR) is to be performed on a
numeric value.
This way, if you want to have multiple options set you can use:
var combined = EAccountStatus.FreeServiceApproved | EAccountStatus.GovernmentAccount
which is equivalent to:
00000001 // =1 - FreeServiceApproved
| 00000010 // =2 - GovernmentAccount
---------
00000011 //= 3 - FreeServiceApproved and GovernmentAccount
this SO thread has a rather good explanation about the flags attribute
<< is doing simply what does i.e. Shift left operation.
As far as why in an enum is concerned, its just a way of evaluating the expression as enums allow expressions (and evaluate them on compile time)
This question already has answers here:
Is there a way to perform a circular bit shift in C#?
(5 answers)
Closed 9 years ago.
Example:
x = 0xF0AA, now when I do x = x << 8, I will get x == 0xAA00.
Right side (8 bits) of new value is filled with zeros. Is there a method int .NET Framework which can fill this bits with that bits from left side (with disapeared part)?
Result should be x == 0xAAF0.
What you want to do is called a circular shift. It's easy enough to emulate with two shifts and an or.
UInt32 RotateLeft(Uint32 n, int howManyBits) {
return n << howManyBits | n >> (32 - howManyBits);
}
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Finding Byte logarithm
I am implemeting the SAFER+ algorithm, this algorithm uses 16 bytes byte-array and performs the operations on Bytes.
The first phase includes XOR and ADDITON funciton with the Subkeys, no problems to mention here.
The second phase is the nonlinear layer which uses POWER and LOGARITHMS on the bytes' values, the problem here is when we take the log "to base 45" of the Value, the result is a floating point double, and this value should be passed to phase 3 as a byte to be handled in the same way of the phase one.
Create an exponentiation table that looks like this:
exp | log
----+----
0 | 1
1 | 45
2 | 226
3 | 147
... | ...
128 | 0
... | ...
255 | 40
---------
The "log" values are 45exp % 257. You'll need an arbitrary precision arithmetic library with a modPow function (raise a number to a power, modulo some value) to build this table. You can see that the value for "exp" 128 is a special case, since normally the logarithm of zero is undefined.
Compute the logarithm of a number by finding the it in the "log" column; the value in the "exp" column of that row is the logarithm.
Here's a sketch of the initialization:
BigInteger V45 = BigInteger.valueOf(45);
BigInteger V257 = BigInteger.valueOf(257);
int[] exp = new int[256];
int[] log = new int[256];
for (int idx = 0; idx < 256; ++idx)
exp[idx] = V45.modPow(BigInteger.valueOf(idx), V257).intValue() % 256;
for (int idx = 0; idx < 256; ++idx)
log[exp[idx]] = idx;
With this setup, for example, log45(131) = log[131] = 63, and 4538 = exp[38] = 59.
You can do this with a Linq expression as follows
inputBytes.Select(b => b == 0 ? (byte)128 : Convert.ToByte(System.Math.Log(Convert.ToDouble(b), 45))).ToArray();
But this will truncate the double, as it has to do...
Edited after looking at SAFER+, it uses the convention that Log45(0)=128 to avoid numeric overflow.