Fastest way to calculate an X-bit bitmask? - c#

I have been trying to solve this problem for a while, but couldn't with just integer arithmetic and bitwise operators. However, I think its possible and it should be fairly easy. What am I missing?
The problem: to get an integer value of arbitrary length (this is not relevant to the problem) with it's X least significant bits sets to 1 and the rest to 0. For example, given the number 31, I need to get an integer value which equals 0x7FFFFFFF (31 least significant bits are 1 and the rest zeros).
Of course, using a loop OR-ing a shifted 1 to an integer X times will do the job. But that's not the solution I'm looking for. It should be more in the direction of (X << Y - 1), thus using no loops.

Try this: (1 << X) - 1

Try this:
uint.MaxValue >> (32 - something)

I think the following should work:
int mask = (int)Math.Pow(2, 31) - 1;
This is a single mathematical expression, but it isn't particularly efficient because calculating the power in this way is not really a good idea. However, since we're calculating a power of 2, we can do the same thing using shift:
int mask = (1 << 31) - 1;

Related

C# So how does this hexadecimal stuff work?

I'm doing some entry level programming challenges at codefights.com and I came across the following question. The link is to a blog that has the answer, but it includes the question in it as well. If only it had an explanation...
https://codefightssolver.wordpress.com/2016/10/19/swap-adjacent-bits/
My concern is with the line of code (it is the only line of code) below.
return (((n & 0x2AAAAAAA) >> 1) | ((n & 0x15555555) << 1)) ;
Specifically, I'm struggling to find some decent info on how the "0x2AAAAAAA" and "0x15555555" work, so I have a few dumb questions. I know they represent binary values of 10101010... and 01010101... respectively.
1. I've messed around some and found out that the number of 5s and As corresponds loosely and as far as I can tell to bit size, but how?
2. Why As? Why 5s?
3. Why the 2 and the 1 before the As and 5s?
4. Anything else I should know about this? Does anyone know a cool blog post or website that explains some of this in more detail?
0x2AAAAAAA is 00101010101010101010101010101010 in 32 bits binary,
0x15555555 is ‭00010101010101010101010101010101‬ in 32 bits binary.
Note that the problem specifies Constraints: 0 ≤ n < 2^30. For this reason the highest two bits can be 00.
The two hex numbers have been "built" starting from their binary representation, that has a particular property (that we will see in the next paragraph).
Now... We can say that, given the constraint, x & 0x2AAAAAAA will return the even bits of x (if we count the bits as first, second, third... the second bit is even), while x & 0x15555555 will return the odd bits of x. By using << 1 and >> 1 you move them of one step. By using | (or) you re-merge them.
0x2AAAAAAA is used to get 30 bits, which is the constraint.
Constraints:
0 ≤ n < 2^30.
0x15555555 also represent 30 bits with bits opposite of other number.
I would start with binary number (101010101010101010101010101010) in the calculator and select hex using programmer calculator to show the number in hex.
you can also use 0b101010101010101010101010101010 too, if you like, depending on language.

What is the most efficient way to check for whether integer is odd?

how do I get the lowest order bit (or any bit) without the modulo operation (since the number may be arbitrarily large) on a series of bits that represent a number in base 2, assuming I know the bit structure of the datatype, in C#, in the most lightweight manner possible?
You could do a bitwise AND with 1, which will get you the last bit.
int n = 3;
bool odd = (n & 1) == 1;

modulo of a number - python vs c#

Lets take the basic arithmetic operation - modulo
I get different outputs depending on different languages.
Python
>>> -1 % 12
11
C#
var res = -1 % 12;
output: res = -1
Why am I seeing such behaviour? Ideally I'd like the output to be 11 in both cases.
Also does anyone know if I can achieve this in C#?
The premise of the question is incorrect. The % operator in C# is not the modulus operator, it is the remainder operator, while in Python it is a modulus operator.
As Eric Lippert Describes, modulus and remainder are the same for all positive numbers, but they handle negative numbers differently.
Despite both C# and Python having a % operator, doesn't mean they both represent a modulus.
It's worth noting that other languages, such as C++ and Java use remainder for the % operator, not modulus, which likely contributed to why C# choose to use remainder as well. Since there isn't a lot of consistency in what is meant by the % operator, I would suggest looking it up in the language docs whenever working with a new language.
In Python, the % operator returns the same sign as the divisor. In C#, it returns the same sign as the dividend. (Also see Modulo operator)
In Python, math.fmod would give similar results to C#.
If you want to obtain 11 in C#, you probably need to say:
(((-1 % 12) + 12) % 12)
Others have explained why you are getting different results in the two languages, but it's important to realize that both answers are correct in the sense that, when you reverse the operations, you get back the original number.
In C#, the result of the integer division -1 / 12 is 0. 0 * 12 is 0. To get back to the original -1, you need to add -1, which is what you got for the remainder operation.
In Python, -1 / 12 is -1. -1 * 12 is -12. To get back to the original -1, you need to add 11. Which, again, is what you got for modulus.
So it's not merely a difference in what operation % performs, there's also a difference in how integer division is performed when the signs of the operands differ between the two languages. The behavior of % is chosen so that the quotient, multiplied by the divisor, and added to the remainder, results in the dividend. Changing how the quotient is calculated necessarily changes how the remainder is calculated.

c# calculation help (TExtractor callid)

I'm pretty useless when it comes to math and I have a problem I need help with.
This has nothing to do with schoolwork, it's in fact about alcatel and the ticketextractor. I have two values that needs to be calculated in a c# application according to a formula specified in their documentation:
"The global callid is equal to: callid1 multiplied by 2 power 32 plus callid2"
As I said I'm not big with maths so that statement says nothing to me. If anyone know how to calculate it i'd appreciate it! Thanks
First thing is you'll need a 64 bit value to store it in. Assuming your callId values are (32 bit) ints, you'd need to do something like this.
int callId1, callId2;
...
long globalCallId = ((long)callId1 << 32) + callId2;
<< is the bit shift operator - shifting 32 bits is the equivalent of multiplying by 2^32.
It's easiest to shift callid1 by 32 bits.
long globalCallId = ((long)callid1 << 32) + callid2;
So global callid = callid1 * 232 + callid2. You can use:
long globalCallID = (callid1 << 32) + callid2
This uses the fact that a << b == a multiplied by 2 to the power of b.

Why arithmetic shift halfs a number only in SOME incidents?

Hey, I'm self-learning about bitwise, and I saw somewhere in the internet that arithmetic shift (>>) by one halfs a number. I wanted to test it:
44 >> 1 returns 22, ok
22 >> 1 returns 11, ok
11 >> 1 returns 5, and not 5.5, why?
Another Example:
255 >> 1 returns 127
127 >> 1 returns 63 and not 63.5, why?
Thanks.
The bit shift operator doesn't actually divide by 2. Instead, it moves the bits of the number to the right by the number of positions given on the right hand side. For example:
00101100 = 44
00010110 = 44 >> 1 = 22
Notice how the bits in the second line are the same as the line above, merely
shifted one place to the right. Now look at the second example:
00001011 = 11
00000101 = 11 >> 1 = 5
This is exactly the same operation as before. However, the result of 5 is due to the fact that the last bit is shifted to the right and disappears, creating the result 5. Because of this behavior, the right-shift operator will generally be equivalent to dividing by two and then throwing away any remainder or decimal portion.
11 in binary is 1011
11 >> 1
means you shift your binary representation to the right by one step.
1011 >> 1 = 101
Then you have 101 in binary which is 1*1 + 0*2 + 1*4 = 5.
If you had done 11 >> 2 you would have as a result 10 in binary i.e. 2 (1*2 + 0*1).
Shifting by 1 to the right transforms sum(A_i*2^i) [i=0..n] in sum(A_(i+1)*2^i) [i=0..n-1]
that's why if your number is even (i.e. A_0 = 0) it is divided by two. (sorry for the customised LateX syntax... :))
Binary has no concept of decimal numbers. It's returning the truncated (int) value.
11 = 1011 in binary. Shift to the right and you have 101, which is 5 in decimal.
Bit shifting is the same as division or multiplication by 2^n. In integer arithmetics the result gets rounded towards zero to an integer. In floating-point arithmetics bit shifting is not permitted.
Internally bit shifting, well, shifts bits, and the rounding simply means bits that fall off an edge simply getting removed (not that it would actually calculate the precise value and then round it). The new bits that appear on the opposite edge are always zeroes for the right hand side and for positive values. For negative values, one bits are appended on the left hand side, so that the value stays negative (see how two's complement works) and the arithmetic definition that I used still holds true.
In most statically-typed languages, the return type of the operation is e.g. "int". This precludes a fractional result, much like integer division.
(There are better answers about what's 'under the hood', but you don't need to understand those to grok the basics of the type system.)

Categories