C# Left Shift Operator - c#

There's a statement a co-worker of mine wrote which I don't completely understand. Unfortunately he's not available right now, so here it is (with modified names, we're working on a game in Unity).
private readonly int FRUIT_LAYERS =
(1 << LayerMask.NameToLayer("Apple"))
| (1 << LayerMask.NameToLayer("Banana"));
NameToLayer takes a string and returns an integer. I've always seen left shift operators used with the constant integer on the right side, not the left, and all the examples I'm finding via Google follow that approach. In this case, I think he's pushing Apple and Banana onto the same relative layer (which I'll use later for filtering). In the future there would be more "fruits" to filter by. Any brilliant stackoverflowers who can give me an explanation of what's happening on those lines?

1 << x is essentially saying "give me a number where the (x+1)-th bit is one and the rest of the numbers are all zero.
x | y is a bitwise OR, so it will go through each bit from 1 to n and if that bit is one in either x or y then that bit will be one in the result, if not it will be zero.
So if LayerMask.NameToLayer("Apple") returns 2 and LayerMask.NameToLayer("Banana") returns 3 then FRUIT_LAYERS will be a number with the 3rd and 4th bits set, which is 1100 in binary, or 12 in base 10.

Your coworker is essentially using an int in place of a bool[32] to try to save on space. The block of code you show is analogous to
bool[] FRUIT_LAYERS = new bool[32];
FRUIT_LAYERS[LayerMask.NameToLayer("Apple")] = true;
FRUIT_LAYERS[LayerMask.NameToLayer("Banana")] = true;
You might want to consider a pattern more like this:
[Flags]
enum FruitLayers : int
{
Apple = 1 << 0,
Banana = 1 << 1,
Kiwi = 1 << 2,
...
}
private readonly FruitLayers FRUIT_LAYERS = FruitLayers.Apple | FruitLayers.Banana;

The code is shifting the binary value 1 to the left, the number of binary places to shift is determined by the Apple and Banana, after both values are shifted the are ORed in a binary way
Example:
Assume apple returns 2 and banana returns 3 you get:
1 << 2 which is 0100 (that means 4 in decimal)
1 << 3 which is 1000 ( that means eight in decimal)
now 0100 bitwise or with 1000 is 1100 which means 12

1 << n is basically an equivalent to 2n.

Related

C# - fast way to compare 2 integers, bit by bit, and output for more than one integer, possible?

I have two input integer numbers and an output list< int> myoutputlist. My inputs are lets say
A=0x110101
B=0x101100
then I have calculated a C integer number depending on A and B numbers.I already coded its algorithm, I can calculate C integer. C integer shows which bits should be changed. 1 value represents changing bits, 0 values represents unchanging bits. Only one bit should be changed in each time. As C integer depends on A and B inputs, sometimes 1 bit, sometimes 3 bits, sometimes 8 bits needs to be changed. In this given A and B values, I have C integer as follows
C=0x 010010 (1 represents changing values; second and fifth bits should be changed in this case)
As C integer has value "1" for two times; there should be 2 results in this case
result 1-Changing only second bit, other bits are same as A(0x110101) :
Change second bit of A => D1=1101 1 1
result 2-Changing only fifth bit, other bits are same as A(0x110101) :
Change fifth bit of A => D2=1 1 0101
What I am thinking is using a for loop, shifting A and C step by step, and using &1 mask to C? And check if it is equal to "1"
for(i=0;i<32;i++)
{int D=(C>>i)&1; //I tried to check if i.th value is equal to 1 or not
if(D==1)
{ int E=(A&(~(2^i))) | ((2^i)&(~B)) //in first brackets, I removed i.th bit of A, then replaced it with "not B" value.
myoutputlist.add(E);
}
}
I need to do lots of calculations but disturbing issue is that I need to check (D==1) for 32 times. I will use it many million times, some calculations take about 2 mins. I am looking for a faster way. Is there any idea, trick?
I hope I understood your question right.
You are looking for the XOR operator.
C = A ^ B
A 110101
B 101100
--------
C 011001
XOR will always be 1 if the two inputs are "different". See:
| A | B | XOR |
|---+---+-----|
| 0 | 0 | 0 |
| 0 | 1 | 1 |
| 1 | 0 | 1 |
| 1 | 1 | 0 |
Then you will be able to loop through the bits of C like this:
for (int i = 0; i < 32; i++)
{
bool bit = (C & (1 << i)) != 0;
}

Merge first n bits of a byte with last 8-n bits of another byte

How can I merge first n bits of a byte with last 8-n bits of another byte?
I know something like below for picking 3 bits from first and 5 from second (Which I have observed in DES encryption algorithm)
zByte=(xByte & 0xE0) | (yByte & 0x1F); But I don't know maths behind why we need to use 0XE0 and 0X1F in this case. So I am trying to understand the details with regards to each bit.
In C#, that would be something like:
int mask = ~((-1) << n);
var result = (x & ~mask) | (y & mask);
i.e. we build a mask that is (for n = 5) : 000....0011111, then we combine (&) one operand with that mask, the other operand with the inverse (~) of the mask, and compose them (|).
You could also probably do something more quickly just using shift operations (avoiding a mask completely) - but only if the data can be treated as unsigned (so Java might struggle here).
It just sounds like you don't understand how boolean arithmetic works? If this is your question it works like this:
0xEO and 0x1F are hexidecimal representations of numbers. If we convert these numbers to binary they would be:
0xE0 = 11100000
0x1F = 00011111
Additionally & (and) and | (or) are bitwise logical operators. To understand logical operators, first remember the 1 = true and 0 = false.
The truth table for & is:
0 & 0 = 0
0 & 1 = 0
1 & 0 = 0
1 & 1 = 1
The truth table for | is:
0 | 0 = 0
0 | 1 = 1
1 | 0 = 1
1 | 1 = 1
So let's breakdown your equation piece by piece. First we will evaluate the code in parenthesis first. We will walk through each number in binary and for the & operator if each operand has a 1 in the same bit position we will return 1. If either number has a 0 then we will return 0. After we finish the evaluation of the operands in the parenthesis we will then take the 2 resulting numbers and apply the | operator bit by bit. If either number has a 1 in the same bit position we will return 1. If both numbers have a 0 in the same bit position we will return 0.
For the sake of discussion, let's say that
xByte = 255 or (FF in hex and 11111111 in binary)
yByte = 0 or (00 in hex and 00000000 in binary)
When you apply the & and | operators we are going to compare each bit one at a time:
zByte = (xByte & 0xEO) | (yByte & 0x1F)
becomes:
zByte = (11111111 & 11100000) | (00000000 & 00011111)
zByte = 111000000 | 00000000
zByte = 11100000
If you understand this and how boolean logic works then you can use Marc Gravell's answer.
The math behind those numbers (0xE0 and 0x1F) is quite simple. First we are exploiting the fact that 0 & <bit> always equals 0 and 1 & <bit> always equals <bit>.
0x1F is 00011111 binary, which means that the first 3 bits will always be 0 after an & operation with another byte - and the last 5 bits will be the same they were in the other byte. Remember that every 1 in a binary number represents a power of 2, so if you want to find the mask mathematically it would be the sum of 2^x from x = 0 to n-1. Then you can find the opposite mask (the one that is 11100000) to extract the first 3 bit, you simply need to subtract the mask from 11111111, and you will get 11100000 (0xE0).
In java,
By using the following function we can get the first n bits of the first Byte and last 8 n bits of the second byte.
public class BitExample {
public static void main(String[] args) {
Byte a = 15;
Byte b = 16;
String mergedValue=merge(4, a, b);
System.out.println(mergedValue);
}
public static String merge(int n, Byte a, Byte b) {
String mergedString = "";
String sa = Integer.toBinaryString(a);
String sb = Integer.toBinaryString(b);
if(n>sa.length()) {
for(int i=0; i<(n-sa.length()); i++) {
mergedString+="0";
}
mergedString+=sa;
}else{
mergedString+=sa.substring(0, n);
}
if(8*n>sb.length()) {
for(int i=0; i<(8*n-sb.length()); i++) {
mergedString+="0";
}
mergedString+=sb;
}
return mergedString;
}
}

How can I detect if a float has a repeating decimal expansion in C#?

I simply need to know how I can detect repeating decimal expansion in floats.
Example:
0.123456789123456789
The repeating portion of the number would be 123456789.
I want to automatize this in C#, is there any smart solution?
There's a nice trick for calculating rational approximations to a given float (based on some properties of Euclid's algorithm for GCDs). We can use this to determine whether or not the "best" approximation is of the form A/(2^a 5^b), if it is then the float terminates (in base 10), if not it will have some repeating component. The tricky bit will be determining which of the approximations is the right one (due to floating point precission issues).
So heres how you get approximate rational expressions.
First iterate x = 1/x - floor(1/x) keeping track of int(x)
x = 0.12341234
1/x = 8.102917
x <= 1/x - 8 = 0.102917
1/x = 9.7165
x <= 1/x - 9 = 0.71265277
1/x = 1.3956
x < 1/x - 1 = 0.3956
...
Next stick the int parts of x into the top row of this table, call them k_i.
The values A_i = A_{i-2} + k_i * A_{i-1} and the same for B_i.
|| 8 | 9 | 1 | 2 | 1 | 1 | 8 | 1 | 1
A = 1 0 || 1 | 9 | 10 | 29 | 39 | 68 | 583 | 651 | 1234
B = 0 1 || 8 | 73 | 81 | 235 | 316 | 551 | 4724 | 5275 | 9999
The rational approximations are then A_n/B_n.
1/8 = 0.12500000000000000 | e = 1.5e-3
9/73 = 0.12328767123287671 | e = 1.2e-4
10/81 = 0.12345679012345678 | e = 4.4e-5
29/235 = 0.12340425531914893 | e = 8.1e-6
39/316 = 0.12341772151898735 | e = 5.4e-6
68/551 = 0.12341197822141561 | e = 3.6e-7
583/4724 = 0.12341236240474174 | e = 2.2e-8
651/5275 = 0.12341232227488151 | e = 1.8e-8
1234/9999 = 0.12341234123412341 | e = 1.2e-9
So if we decide our error is low enough at the 1234/9999 stage, we note that 9999 can not be written in the form 2^a 5^b, and thus our decimal expansion is repeating.
Note that while this seems to require a lot of steps we can get faster convergence if we use
x = 1/x - round(1/x) (and keep track of round round(1/x) instead). In that case the table becomes
8 10 -4 2 9 -2
1 0 1 10 -39 -68 -651 1234
0 1 8 81 -316 -551 -5275 9999
This gives you a subset of the previous results, in fewer steps.
It is interesting to note that the fraction A_i/B_i is always such that A_i and B_i have no common factors so you dont event need to worry about canceling out factors or anything like that.
For comparison lets look at the expansion for x = 0.123. The table we get is:
8 8 -3 -5
1 0 1 8 -23 123
0 1 8 65 -187 1000
Then our sequence of approximations is
1/8 = 0.125 e = 2.0e-3
8/65 = 0.12307.. e = 7.6e-5
23/187 = 0.12299.. e = 5.3e-6
123/1000 = 0.123 e = 0
And we see that 123/1000 is exactly the fraction we want and since 1000 = 10^3 = 2^3 5^3 our fraction is terminating.
If you actually want to find out what the repeating part of the fraction is (what digits and what period) you need to do some additional tricks. This involves factoring the denominator and finding the lowest number (10^k-1) with all those factors (other than 2 and 5), then k will be your period. So for our top case we found A = 9999 = 10^4-1 (and thus 10^4-1 contains all the factors of A - we were kind of lucky here...) so the period of the repeating part is 4. You can find more details about this final part here.
A final and important aspect of not of this algorithm is that it does not require all the digits to mark a decimal expansion as repeating. Consider x = 0.34482, this has the table:
3 -10 -156
1 0 1 -10 .
0 1 3 -29 .
We get a very accurate approximation at the second entry and stop there, concluding that our fraction is probably 10/29 (as that gets use within 1e-5) and from the tables in the link above we can discern that its period will be 28 digits. This could never be determined using string searches on the short version of the number, which would require at least 57 digits of the number to be known.
you can't detect period like in your example as for representation in base 10, precision of float is 7 digits.
http://msdn.microsoft.com/en-us/library/aa691146%28v=vs.71%29.aspx
You can isolate the fractional (post-period) part of the number like this:
value - Math.Floor(value)
If you do this with the double value "1.25", you'll end up with the value "0.25". Thus, you'll have isolated the part "to the right of the period". Of course, you'll have it as a double between 0 and 1, and not an integer as your question seems to require.
Your question states that you need to "detect periods in floats". If all you need is to determine if a fractional part exists, the following code will approximately work:
value != Math.Floor(value)
Personally I would convert it to a String, snag the substring of everything after the period, then convert to the data type you need it in. For example (It's been years since I wrote any C# so forgive any syntax problems):
float checkNumber = 8.1234567;
String number = new String( checkNumber ); // If memory serves, this is completely valid
int position = number.indexOf( "." ); // This could be number.search("."), I don't recall the exact method name off the top of my head
if( position >= 0 ){ // Assuming search or index of gives a 0 based index and returns -1 if the substring is not found
number = number.substring( position ); // Assuming this is the correct method name to retrieve a substring.
int decimal = new Int( number ); // Again, if memory serves this is completely valid
}
You can't.
Floating-point has finite precision. Every value of type float is an integer multiple of an integer power of 2.0 (X * 2Y), where X and Y are (possibly negative) integers). Since 10 is a multiple of 2, every value of type float can be represented exactly in a finite number of decimal digits.
For example, although you might expect 1.0f/3.0f to be represented as a repeating decimal (or binary) number, in fact float can only hold a close approximation of the mathematical value, one that isn't a repeating decimal (unless you count the repeating 0 that follows the non-zero digits). The stored value is likely to be exactly 0.3333333432674407958984375; only the first 7 or so digits after the decimal point are significant.
I don't think that there's solution in general (at least, with float/double):
period can bee too long for float (or even double);
float/double are approximate values.
E.g., here's a result of division (double)1/(double)97:
0.010309278350515464
Indeed, it is a repeating decimal with 96 repeating digits in period. How to detect this, if you only have 18 digits after decimal point?
Even in decimal there's not enough digits:
0.0103092783505154639175257732

How to convert from RGB555 to RGB888 in c#?

I need to convert 16-bit XRGB1555 into 24-bit RGB888. My function for this is below, but it's not perfect, i.e. a value of 0b11111 wil give 248 as the pixel value, not 255. This function is for little-endian, but can easily be modified for big-endian.
public static Color XRGB1555(byte b0, byte b1)
{
return Color.FromArgb(0xFF, (b1 & 0x7C) << 1, ((b1 & 0x03) << 6) | ((b0 & 0xE0) >> 2), (b0 & 0x1F) << 3);
}
Any ideas how to make it work?
You would normally copy the highest bits down to the bottom bits, so if you had five bits as follows:
Bit position: 4 3 2 1 0
Bit variable: A B C D E
You would extend that to eight bits as:
Bit position: 7 6 5 4 3 2 1 0
Bit variable: A B C D E A B C
That way, all zeros remains all zeros, all ones becomes all ones, and values in between scale appropriately.
(Note that A,B,C etc aren't supposed to be hex digits - they are variables representing a single bit).
I'd go with a lookup table. Since there are only 32 different values it even fits in a cache-line.
You can get the 8 bit value from the 5 bit value with:
return (x<<3)||(x>>2);
The rounding might not be perfect though. I.e. the result isn't always closest to the input, but it never is further away that 1/255.

What does the CreateMask function of BitVector32 do?

What does the CreateMask() function of BitVector32 do?
I did not get what a Mask is.
Would like to understand the following lines of code. Does create mask just sets bit to true?
// Creates and initializes a BitVector32 with all bit flags set to FALSE.
BitVector32 myBV = new BitVector32( 0 );
// Creates masks to isolate each of the first five bit flags.
int myBit1 = BitVector32.CreateMask();
int myBit2 = BitVector32.CreateMask( myBit1 );
int myBit3 = BitVector32.CreateMask( myBit2 );
int myBit4 = BitVector32.CreateMask( myBit3 );
int myBit5 = BitVector32.CreateMask( myBit4 );
// Sets the alternating bits to TRUE.
Console.WriteLine( "Setting alternating bits to TRUE:" );
Console.WriteLine( " Initial: {0}", myBV.ToString() );
myBV[myBit1] = true;
Console.WriteLine( " myBit1 = TRUE: {0}", myBV.ToString() );
myBV[myBit3] = true;
Console.WriteLine( " myBit3 = TRUE: {0}", myBV.ToString() );
myBV[myBit5] = true;
Console.WriteLine( " myBit5 = TRUE: {0}", myBV.ToString() );
What is the practical application of this?
It returns a mask which you can use for easier retrieving of interesting bit.
You might want to check out Wikipedia for what a mask is.
In short: a mask is a pattern in form of array of 1s for the bits that you are interested in and 0s for the others.
If you have something like 01010 and you are interested in getting the last 3 bits, your mask would look like 00111. Then, when you perform a bitwise AND on 01010 and 00111 you will get the last three bits (00010), since AND only is 1 if both bits are set, and none of the bits beside the first three are set in the mask.
An example might be easier to understand:
BitVector32.CreateMask() => 1 (binary 1)
BitVector32.CreateMask(1) => 2 (binary 10)
BitVector32.CreateMask(2) => 4 (binary 100)
BitVector32.CreateMask(4) => 8 (binary 1000)
CreateMask(int) returns the given number multiplied by 2.
NOTE: The first bit is the least significant bit, i.e. the bit farthest to the right.
BitVector32.CreateMask() is a substitution for the left shift operator (<<) which in most cases results in multiplication by 2 (left shift is not circular, so you may start loosing digits, more is explained here)
BitVector32 vector = new BitVector32();
int bit1 = BitVector32.CreateMask();
int bit2 = BitVector32.CreateMask(bit1);
int bit3 = 1 << 2;
int bit5 = 1 << 4;
Console.WriteLine(vector.ToString());
vector[bit1 | bit2 | bit3 | bit5] = true;
Console.WriteLine(vector.ToString());
Output:
BitVector32{00000000000000000000000000000000}
BitVector32{00000000000000000000000000010111}
Check this other post link text.
And also, CreateMask does not return the given number multiplied by 2.
CreateMask creates a bit-mask based on an specific position in the 32-bit word (that's the paramater that you are passing), which is generally x^2 when you are talking about a single bit (flag).
I stumbled upon this question trying to find out what CreateMask does exactly. I did not feel the current answers answered the question for me. After some reading and experimenting, I would like to share my findings:
Basically what Maksymilian says is almast correct: "BitVector32.CreateMask is a substitution for the left shift operator (<<) which in most cases results in multiplication by 2".
Because << is a binary operator and CreateMask only takes one argument, I would like to add that BitVector32.CreateMask(x) is equivalant to x << 1.
Bordercases
However, BitVector32.CreateMask(x) is not equivalant to x << 1 for two border cases:
BitVector32.CreateMask(int.MinValue):
An InvalidOperationException will be thrown. int.MinValue corresponds to 10000000000000000000000000000000. This seems bit odd. Especially considering every other value with a 1 as the leftmost bit (i.e. negative numbers) works fine. In contrast: int.MinValue << 1 would not throw an exception and just return 0.
When you call BitVector32.CreateMask(0) (or BitVector32.CreateMask()). This will return 1
(i.e. 00000000000000000000000000000000 becomes 00000000000000000000000000000001),
whereas 0 << 1 would just return 0.
Multiplication by 2
CreateMask almost always is equivalent to multiplication by 2. Other than the above two special cases, it differs when the second bit from the left is different from the leftmost bit. An int is signed, so the leftmost bit indicates the sign. In that scenario the sign is flipped. E.g. CreateMask(-1) (or 11111111111111111111111111111111) results in -2 (or 11111111111111111111111111111110), but CreateMask(int.MaxValue) (or 01111111111111111111111111111111) also results in -2.
Anyway, you probably shouldn't use it for this purpose. As I understand, when you use a BitVector32, you really should only consider it a sequence of 32 bits. The fact that they use ints in combination with the BitVector32 is probably just because it's convenient.
When is CreateMask useful?
I honestly don't know. It seems from the documentation and the name "previous" of the argument of the function that they intended it to be used in some kind of sequence: "Use CreateMask() to create the first mask in a series and CreateMask(int) for all subsequent masks.".
However, in the code example, they use it to create the masks for the first 5 bits, to subsequently do some operations on those bits. I cannot imagine they expect you to write 32 calls in a row to CreateMask to be able to do some stuff with the bits near the left.

Categories

Resources