Bitwise operations - c#

A) (Int32)X | ((Int32)Y << 16);
B) (Int32)X + (Int32)Y * (Int32)Int16.MaxValue;
Shouldn't both be equivalent? I know from testing that the first works as expected, but for some reason the second doesn't. Both X and Y are shorts (Int16), and the return type is an integer (Int32).
Shouldn't Y << 16 <=> Y * Int16.MaxValue?

To get the desired behaviour, you need to multiply with 0x10000 (i.e. UInt16.MaxValue+1). Int16.MaxValue is 0x7fff.
5 << 16
327680
5 * 0x10000
327680
Compare to the decimal system: If you want to "shift" the number 5 to 500, you need to multiply with 100, not 99 :-)

There are 2 problems with your second approach:
Int16 is signed, so the max value is actually only 15 bits.
The maximum value that can be represented by 16 bits is 2^16 - 1.

Right-shift 16 bits = * 2^16
But:
Int16.MaxValue = 2^15-1
I think that you want an unsigned 16-bit max value + 1

Overlooking your MaxValue being one less than a power of two, and since you have a bigger problem to cover first:
The OR and SUM operations are not similar. When you are working with 32-bit integers and 16-bit shifts, there will be carries with your + operation and bit-wise OR'ing with the OR operation.
So, the two ways are quite different.
Then, of course, the MaxValue interpretation makes your two 'shift' attempts different. It should be (x * MaxValue + x) or (x * (MaxValue+1)).

Related

C# - What's the fastest way to convert a number to the smallest BitArray

I would like to convert a number to a BitArray, with the resulting BitArray only being as big as it needs to be.
For instance:
BitArray tooBig = new BitArray(new int[] { 9 });
results in a BitArray with a length of 32 bit, however for the value 9 only 4 bits are required. How can I create BitArrays which are only as long as they need to be? So in this example, 4 bits. Or for the number 260 I expected the BitArray to be 9 bits long
You can figure out all the bits first and then create the array by checking if the least significant bit is 1 or 0 and then right shifting until the number is 0. Note this will not work for negative numbers where the 32nd bit would be 1 to indicate the sign.
public BitArray ToShortestBitArray(int x)
{
var bits = new List<bool>();
while(x > 0)
{
bits.Add((x & 1) == 1);
x >>= 1;
}
return new BitArray(bits.ToArray());
}
Assuming you are working with exclusively unsigned integers, the number of bits you need is equal to the base 2 logarithm of the (number+1), rounded up.
Counting the bits is probably the easiest solution.
In JavaScript for example...
// count bits needed to store a positive number
const bits = (x, b = 0) => x > 0 ? bits(x >> 1, b + 1) : b;

C# formula to determine index

I have a maths issue within my program. I think the problem is simple but I'm not sure what terms to use, hence my own searches returned nothing useful.
I receive some values in a method, the only thing I know (in terms of logic) is the numbers will be something which can be duplicated.
In other words, the numbers I could receive are predictable and would be one of the following
1
2
4
16
256
65536
etc
I need to know at what index they appear at. In othewords, 1 is always at index 0, 2 at index 1, 4 at index 3, 16 is at index 4 etc.
I know I could write a big switch statement but I was hoping a formula would be tidier. Do you know if one exists or any clues as the names of the math forumula's I'm using.
The numbers you listed are powers of two. The inverse function of raising a number to a power is the logarithm, so that's what you use to go backwards from (using your terminology here) a number to an index.
var num = 256;
var ind = Math.Log(num, 2);
Above, ind is the base-2 logarithm of num. This code will work for any base; just substitute that base for 2. If you are only going to be working with powers of 2 then you can use a special-case solution that is faster based on the bitwise representation of your input; see What's the quickest way to compute log2 of an integer in C#?
Try
Math.Log(num, base)
where base is 2
MSDN: http://msdn.microsoft.com/en-us/library/hd50b6h5.aspx
Logarithm will return to You power of base from you number.
But it's in case if your number really are power of 2,
otherwise you have to understand exactly what you have, what you need
It also look like numbers was powered to 2 twice, so that try this:
private static int getIndexOfSeries(UInt64 aNum)
{
if (aNum == 1)
return 0;
else if (aNum == 2)
return 1;
else
{
int lNum = (int)Math.Log(aNum, 2);
return 1+(int)Math.Log(lNum, 2);
}
}
Result for UInt64[] Arr = new UInt64[] { 1, 2, 4, 16, 256, 65536, 4294967296 } is:
Num[0] = 1
Num[1] = 2
Num[2] = 4
Num[3] = 16
Num[4] = 256
Num[5] = 65536
Num[6] = 4294967296 //65536*65536
where [i] - index
You should calculate the base 2 logarithm of the number
Hint: For the results:
0 2
1 4
2 16
3 256
4 65536
5 4294967296
etc.
The formula is, for a give integer x:
Math.Pow(2, Math.Pow(2, x));
that is
2 to the power (2 to the power (x) )
Once the formula is known, one could solve it for x (I won't go through that since you already got an answer).

How to remove a number from another number using bitwise operators?

How do I remove for example 2 from 123 and returns 13, by using bitwise operators? I have no idea how to do this.. it's possible? Thanks in advance.
What you're suggesting is possible, but wouldn't really make sense to do. Below are the values representations in bits (only showing relevant bits, everything further left is a zero):
2: 000010 || 123: 1111011 || 13: 001101
There's no logical way to change 123 into 13 with bitwise operations. It would better to turn it into a string or character array, remove the two then cast it back to an int.
What other cases are there? It may be possible to generalize this at an integer level if there is some sort of pattern, otherwise you're really just looking at string replacement.
The 2 in 123 is actually 2E1 (10100), and the 2 in 1234 would be 2E2 (11001000) neither of which are related to 2 (10), at least in bitwise form. Also, the "number" on the right side of the removed number would need to be added to the number on the left side of the removed number / 10.
i.e, to go from 123 to 13:
Located "2".
Number on left (x): 100
Number on right (y): 3
y + (x / 10) = 13
and to go from 1324 to 134
Located "2"
Number on left (x): 1300
Number on right (y): 4
y + (x / 10) = 134
Unless there's some pattern (i.e you know what positions the numbers are in), you'll just have to .ToString() the number, then do a .Replace("2", ""), before doing an int.Parse() on the result.
EDIT: Someone upvoted this answer and I realised my previous implementation was unnecessarily complicated. It is relatively straightforward to 'iterate' over the digits in a base-10 number and shouldn't require recursion.
New solution below, performance is better but this is a huge micro-optimisation:
static int OmitDigit(int number, int digit) {
var output = 0;
var multiplier = 1;
while (number > 0) {
var n = number % 10;
number /= 10;
if (n != digit) {
output += (n * multiplier);
multiplier *= 10;
}
}
return output;
}
Result:
1554443
Since we're working with base 10 numbers, manipulation in base 2 is ugly to say the least. Using some math, removing the nth digit from k, and shifting over is
(k/pow(10,n))*pow(10, n-1) + k%pow(10, n-1)
In base 2, the << and >> operator acts like multiplying by a pow(2, n), and & with a mask does the work of %, but in base 10 the bits don't line up.
This is very awkward, but if you really do must have bitwise operations only, I suggest you convert the number to BCD. Once in BCD, you basically have an hexadecimal numbers with digits between 0 and 9, so removing a digit is very simple. Once you're done, convert back to binary.
I don't believe anybody would want to do that.

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.

Min and Max value of integral type in C#

Whats the mathematical formulae to calculate the MIN and MAX value of an integral type using your calculator. I know you can use Integer.Max or Integer.Min etc or look it up on msdn however I want to know how to calculate it.
For unsigned types:
Min value = 0
Max value = (2 ** (number of bits)) - 1
So, for UInt32:
Min value = 0
Max value = (2 ** 32) - 1
= 4294967296 - 1
= 4294967295
For signed types:
Min value = 0 - (2 ** (number of bits - 1))
Max value = (2 ** (number of bits - 1)) - 1
So, for Int32:
Min value = 0 - (2 ** (32 - 1))
= 0 - (2 ** 31)
= 0 - 2147483648
= -2147483648
Max value = (2 ** (32 - 1)) - 1
= (2 ** 31) - 1
= 2147483648 - 1
= 2147483647
I'm using a 32bits signed integer in this example.
31 bits are used for the value creating 2^31 possibilities. As zero has to be included, you have to subtract one.
2^31-1
When negative, zero doesn't have to be included, thus you get the full range.
-2^31
In case of a unsigned integer, the max is simply 2^32-1, and the min 0.
You need to know how many bits the type is and whether it is signed or not.
For example, an int is 32-bits in C# and is signed. This means there are 31 bits to represent the number (1 bit is used to determine negative or postive). So you would calculate 231 and subtract one which is 2147483647, (which is what Integer.MaxValue returns).
Similary a byte is 8 bits and not signed so the max value is 28 -1 or 255.
If your calculator has a decimal-to-binary conversion (dec-to-hex would also work), try converting Int32.MaxValue and see if you spot the pattern ...
An example for your question answer
int signed:
Min=(1 << ((sizeof(int) * 8) - 1));
Max=~(1 << ((sizeof(int) * 8) - 1));
also
Min=~(int)((~((uint)0))>>1);
Max=(int)((~((uint)0))>>1);
int unsigned:
Min=0;
Max=~((uint)0);
The Min/Max value of an Integer variable is derived from the amount of bits used (usually to the power of 2, ie 2bits, 4bits, 8bits). An INT in C# uses 32 bits, and as such can have a MAX value of 4,294,967,295 - as this is the maximum value 32 bits of data can represent - as is my understanding, anyway.
http://en.wikipedia.org/wiki/Integer_%28computer_science%29
I believe you'll find this helpful:
Integer (Computer Science) # Wikipedia

Categories

Resources