Well I want to generate pseudo-random bits for a mathematical problem. The Bit size is user fed. But unlike normal problems there's a small twist here. The mathematical problem also gives valid results if the bits begin with 0's and literally match the size input by user.
Example: For User Input 4, all the following are valid outputs:
-> 0000
-> 0001
-> 1000
-> 0100
etc.
I am using this function to generate the numbers now:
int randomChoice = choice.Next(1 << (input - 1), (1 << input) - 1);
bitSize = randomChoice;
Is there any other way of random bit generation that may begin with 0's as long as it follows the literal bit length in C# without going into complex array manipulation?
The following line:
int randomChoice = choice.Next(1 << (input - 1), (1 << input) - 1)
for input = 4 is equivalent to:
int randomChoice = choice.Next(8, 15);
Which will per MSDN documentation pick one of the following values: 8, 9, 10, 11, 12, 13, 14 - randomly. Notice that the value 15 will not be picked as the documentation states clearly that the lower bound (8) is )inclusive_ while the upper bound (15) is exclusive.
Those values in binary are:
8 : 1000
9 : 1001
10: 1010
11: 1011
12: 1100
13: 1101
14: 1110
I believe what #Jon Skeet was saying is that you are generating random numbers that always have the MSB (left-most bit) set. And are thus missing out on all values that fit in 4 bits that would start with 0 (have the MSB unset).
I would also point out that you should probably include value 15 here, since that also fits in the 4 bits. So, with the two modifications, the line of code should read:
int randomChoice = choice.Next(0, (1 << input));
That would generate all values from 0 to 15, inclusive:
0 : 0000
1 : 0001
2 : 0010
3 : 0011
...
13: 1101
14: 1110
15: 1111
Is that what you're looking for?
In your previous question, you accepted an answer that improved your original code. Problem was, your code was wrong to begin with. You want only a single random bit. You'll need to do it like this instead:
int maxBit = AskUserForMaxBit();
int randomBit = choice.Next(1, maxBit+1);
int randomValue = 1 << (randomBit - 1);
return Convert.ToString(randomValue, 2);
Related
I have do not have much knowledge of C and I'm stuck with a problem since one of my colleague is on leave.
I have a 32 bit number and i have to extract bits from it. I did go through a few threads but I'm still not clear how to do so. I would be highly obliged if someone can help me.
Here is an example of what I need to do:
Assume hex number = 0xD7448EAB.
In binary = 1101 0111 0100 0100 1000 1110 1010 1011.
I need to extract the 16 bits, and output that value. I want bits 10 through 25.
The lower 10 bits (Decimal) are ignored. i.e., 10 1010 1011 are ignored.
And the upper 6 bits (Overflow) are ignored. i.e. 1101 01 are ignored.
The remaining 16 bits of data needs to be the output which is 11 0100 0100 1000 11 (numbers in italics are needed as the output).
This was an example but I will keep getting different hex numbers all the time and I need to extract the same bits as I explained.
How do I solve this?
Thank you.
For this example you would output 1101 0001 0010 0011, which is 0xD123, or 53,539 decimal.
You need masks to get the bits you want. Masks are numbers that you can use to sift through bits in the manner you want (keep bits, delete/clear bits, modify numbers etc). What you need to know are the AND, OR, XOR, NOT, and shifting operations. For what you need, you'll only need a couple.
You know shifting: x << y moves bits from x *y positions to the left*.
How to get x bits set to 1 in order: (1 << x) - 1
How to get x bits set to 1, in order, starting from y to y + x: ((1 << x) -1) << y
The above is your mask for the bits you need. So for example if you want 16 bits of 0xD7448EAB, from 10 to 25, you'll need the above, for x = 16 and y = 10.
And now to get the bits you want, just AND your number 0xD7448EAB with the mask above and you'll get the masked 0xD7448EAB with only the bits you want. Later, if you want to go through each one, you'll need to shift your result by 10 to the right and process each bit at a time (at position 0).
The answer may be a bit longer, but it's better design than just hard coding with 0xff or whatever.
OK, here's how I wrote it:
#include <stdint.h>
#include <stdio.h>
main() {
uint32_t in = 0xd7448eab;
uint16_t out = 0;
out = in >> 10; // Shift right 10 bits
out &= 0xffff; // Only lower 16 bits
printf("%x\n",out);
}
The in >> 10 shifts the number right 10 bits; the & 0xffff discards all bits except the lower 16 bits.
I want bits 10 through 25.
You can do this:
unsigned int number = 0xD7448EAB;
unsigned int value = (number & 0x3FFFC00) >> 10;
Or this:
unsigned int number = 0xD7448EAB;
unsigned int value = (number >> 10) & 0xFFFF;
I combined the top 2 answers above to write a C program that extracts the bits for any range of bits (not just 10 through 25) of a 32-bit unsigned int. The way the function works is that it returns bits lo to hi (inclusive) of num.
#include <stdio.h>
#include <stdint.h>
unsigned extract(unsigned num, unsigned hi, unsigned lo) {
uint32_t range = (hi - lo + 1); //number of bits to be extracted
//shifting a number by the number of bits it has produces inconsistent
//results across machines so we need a special case for extract(num, 31, 0)
if(range == 32)
return num;
uint32_t result = 0;
//following the rule above, ((1 << x) - 1) << y) makes the mask:
uint32_t mask = ((1 << range) -1) << lo;
//AND num and mask to get only the bits in our range
result = num & mask;
result = result >> lo; //gets rid of trailing 0s
return result;
}
int main() {
unsigned int num = 0xd7448eab;
printf("0x%x\n", extract(num, 10, 25));
}
I understand that:
int bit = (number >> 3) & 1;
Will give me the bit 3 places from the left, so lets say 8 is 1000 so that would be 0001.
What I don't understand is how "& 1" will remove everything but the last bit to display an output of simply "1". I know that this works, I know how to get a bit from an int but how is it the code is extracting the single bit?
Code...
int number = 8;
int bit = (number >> 3) & 1;
Console.WriteLine(bit);
Unless my boolean algebra from school fails me, what's happening should be equivalent to the following:
*
1100110101101 // last bit is 1
& 0000000000001 // & 1
= 0000000000001 // = 1
*
1100110101100 // last bit is 0
& 0000000000001 // & 1
= 0000000000000 // = 0
So when you do & 1, what you're basically doing is to zero out all other bits except for the last one which will remain whatever it was. Or more technically speaking you do a bitwise AND operation between two numbers, where one of them happens to be a 1 with all leading bits set to 0
8 = 00001000
8 >> 1 = 00000100
8 >> 2 = 00000010
8 >> 3 = 00000001
If you use mask 1 = 000000001 then you have:
8 >> 3 = 000000001
1 = 000000001
(8 >> 3) & 1 = 000000001
Actually this is not hard to understand.
the "& 1" operation is just set all bits of the value to the "0", except the bit, which placed in the same position as the valuable bit in the value "1"
previous operation just shifts the all bits to the right. and places the checked bit to the position which won't be setted to "0" after operation "& 1"
fo example
number is 1011101
number >> 3 makes it 0001011
but (number >> 3) & 1 makes it 0000001
When u right shift 8 you get 0001
0001 & 0001 = 0001 which converted to int gives you 1.
So, when a value 0001 has been assigned to an int, it will print 1 and not 0001 or 0000 0001. All the leading zeroes will be discarded.
How to remove the leftmost bit?
I have a hexadecimal value BF
Its binary representation is 1011 1111
How can I remove the first bit, which is 1, and then it will become 0111 1110?
How to add "0" also to its last part?
To set bit N of variable x to 0
x &= ~(1 << N);
How it works: The expression 1 << N is one bit shifted N times to the left. For N = 7, this would be
1000 0000
The bitwise NOT operator ~ inverts this to
0111 1111
Then the result is bitwise ANDed with x, giving:
xxxx xxxx
0111 1111
--------- [AND]
0xxx xxxx
Result: bit 7 (zero-based count starting from the LSB) is turned off, all others retain their previous values.
To set bit N of variable x to 1
x |= 1 << N;
How it works: this time we take the shifted bit and bitwise OR it with x, giving:
xxxx xxxx
1000 0000
--------- [OR]
1xxx xxxx
Result: Bit 7 is turned on, all others retain their previous values.
Finding highest order bit set to 1:
If you don't know which is the highest bit set to 1 you can find out on the fly. There are many ways of doing this; a reasonable approach is
int x = 0xbf;
int highestSetBit = -1; // assume that to begin with, x is all zeroes
while (x != 0) {
++highestSetBit;
x >>= 1;
}
At the end of the loop, highestSetBit will be 7 as expected.
See it in action.
int i=0xbf;
int j=(i<<1) & 0xff;
or you could do:
(i*2) && 0xff
if you'd rather not do bit twiddling. >>1 is the equivalent of /2, and <<1 is the equivalent of *2.
Given that i have a uint value of 2402914, and i would like to grab the leftmost 17 bits, where is the fault in my logic by doing this code:
int testop = 0;
byte[] myArray = BitConverter.GetBytes(2402914);
fixed (byte* p = &myArray[0])
{
testop = *p >> 15;
}
my expected output is
50516.
You might want to get your expectations to match reality. A right-shift is equivalent to dividing by 2. You are effectively dividing by 2 fifteen times, which is the same as saying you are dividing by 2^15 = 32768. Note that 2402914 / 32768 = 73 (truncating the remainder).
Therefore, I would expect the result to be 73, not 50516.
In fact,
2402914_10 = 0000 0000 0010 0100 1010 1010 0110 0010_2
So that the left-most seventeen bits are
0000 0000 0010 0100 1
Note that
0000 0000 0010 0100 1 = 1 * 1 + 0 * 2 + 0 * 4 + 1 * 8 + 0 * 16 + 0 * 32 + 1 * 64
= 73
Note that you can obtain this result more simply with
int testop = 2402914 >> 15;
*p just gives you the first byte; it is equivalent to p[0]. You'll have to use shifting and ORing to combine bits from the first three bytes (or the last three bytes, depending on endianness...)
If this code is not a simplified version of something more complicated and you're actually trying to just extract the leftmost 17 bits from an int, this should do:
int testop = (someInt >> 15) & 0x1ffff;
(Edit: Added & 0x1ffff to make it work for negative integers too; thanks to #James.)
Wow, this has been a really fun puzzle to figure out. Not the programming part, but trying to figure out where you got the number 50516 and what you are trying to do with your code. It looks like you are taking the 16 least significant bits and ROTATING them LEFT 9 bits.
2402914: 0000 0000 0010 0100 1010 1010 0110 0010
left 9: 0100 1001 0101 0100 1100 010
match: ^^^^ ^^^
>>50516: 1100 0101 0101 0100
match: ^ ^^^^ ^^^^
right 7: 1 0101 0100 110 0010
int value2 = value & 0xffff;
int rotate9left = ((value2 << 9) & 0xffff) | ((value2) >> (16 - 9));
I don't know why you are using a byte array, but it seems like you think your fixed() statement is looping through the array, which it is not. Your statement in the fixed block is taking the byte value at myArray[0] and SHIFTing it right 15 bits (shifting fills with 0s as opposed to rotating which wraps the front bits around to the back). Any thing over 8 would give you zero.
From what I understand, you can apply the bit-shift operator directly to the int datatype, rather than going through the trouble of the unsafe code.
For example:
2402914 >> 15 = 73
This ties to the result predicted by Jason.
Further, I note that
2402914 >> 5 = 75091
and 2402914 >> 6 = 37545
This suggests that your required result cannot be achieved by any similar right shift.
Is there any difference between Arithmetic + and bitwise OR. In what way this is differing.
uint a = 10;
uint b = 20;
uint arithmeticresult = a + b;
uint bitwiseOR = a | b;
Both the results are 30.
Edit : Small changes to hide my stupidity.
(10 | 20) == 10 + 20 only because the 1-bits do not appear in the same digit.
1010 = 10
or 10100 = 20
————————
11110 = 30
However,
11 = 3 11 = 3
or 110 = 6 + 110 = 6
—————— ——¹——————
111 = 7 1001 = 9
# ^ ^
# (1|1==1) (1+1=2)
Counterexample:
2 + 2 == 42 | 2 == 2
Bitwise OR means, for each bit position in both numbers, if one or two bits are on, then the result bit is on. Example:
0b01101001
|
0b01011001
=
0b01111001
(0b is a prefix for binary literals supported in some programming languages)
At the bit level, addition is similar to bitwise OR, except that it carries:
0b01101001
+
0b01011001
=
0b11000010
In your case, 10+20 and 10|20 happen to be the same because 10 (0b1010) and 20 (0b10100) have no 1s in common, meaning no carry happens in addition.
Try setting a = 230 and b = 120. And you'll observer the difference in results.
The reason is very simple. In the arithmentic addition operation the bit-wise add operation may generate carry bit which is added in the next bit-wise addition on the bit-pair available on the subsequent position. But in case of bit wise OR it just performs ORing which never generates a carry bit.
The fact that you're getting same result in your case is that the
numbers co-incidentally don't generate any
carry-bit during addition.
Bit-wise arithmetic Addition
alt text http://www.is.wayne.edu/drbowen/casw01/AnimAdd.gif
Bitwise OR goes through every bit of two digits and applies the following truth table:
A B | A|B
0 0 | 0
0 1 | 1
1 0 | 1
1 1 | 1
Meanwhile the arithmetic + operator actually goes through every bit applying the following table (where c is the carry-in, a and b are the bits of your number, s is the sum and c' is the carry out):
C A B | S C'
0 0 0 | 0 0
0 0 1 | 1 0
0 1 0 | 1 0
0 1 1 | 0 1
1 0 0 | 1 0
1 0 1 | 0 1
1 1 0 | 0 1
1 1 1 | 1 1
For obvious reasons, the carry-in starts-off being 0.
As you can see, sum is actually a lot more complicated. As a side effect of this, though, there as an easy trick you can do to detect overflow when adding positive signed numbers. More specifically, we expect that a+b >= a|b if that fails then you have an overflow!
The case when the two numbers will be the same is when every time a bit in one of the two numbers is set, the corresponding bit int he second number is NOT set. That is to say that you have three possible states: either both bits aren't set, the bit is set in A but not B, or the bit is set in B but not A. In that case the arithmetic + and the bit-wise or would produce the same result... as would the bitwise xor for that matter.
Using arithmetic operations to manipulate bitmasks can produce unexpected results and even overflow. For instance, turning on the n-th bit of a bitmask if it is already on will turn off the n-th bit and turn on the n+1-th bit. This will cause overflow if there are only n-bits.
Example of turning on bit 2:
Arithmetic ADD Bitwise OR
0101 0101
+ 0100 | 0100
---- ----
1001 0101 //expected result: 0101
Like-wise, using arithmetic subtract to turn off the n-th bit will fail if the n-th bit was not already on.
Example of turning off bit 2:
Arithmetic SUB Bitwise AND~
0001 0001
- 0100 &~ 0100
---- ----
0001 0001
+ 1100 & 1011
---- ----
1101 0001 //expected result: 0001
So bitwise operators are safer than arithmetic operators when you are working with bitmasks.
The following bitwise operations have analogous arithmetic operations:
Bitwise Arithmetic
Check n-th bit x & (1 << n) !(x - (1 << n))
Turn on n-th bit x |= (1 << n) x += (1 << n)
Turn off n-th bit x &= ~(1 << n) x -= (1 << n)
Try a = 1 and b = 1 ;)
+ and | have different when two bits at the same positions are 1
00000010
OR
00000010
Result
00000010
VS
00000010
+
00000010
Result
00000100