Understanding this snippet of code _num = (_num & ~(1L << 63)); - c#

Can any explain what this section of code does: _num = (_num & ~(1L << 63));
I've have been reading up on RNGCryptoServiceProvider and came across http://codethinktank.blogspot.co.uk/2013/04/cryptographically-secure-pseudo-random.html with the code, I can follow most the code except for the section above.
I understand it ensuring that all numbers are positive, but I do not know how its doing that.
Full code
public static long GetInt64(bool allowNegativeValue = false)
{
using (RNGCryptoServiceProvider _rng = new RNGCryptoServiceProvider())
{
byte[] _obj = new byte[8];
_rng.GetBytes(_obj);
long _num = BitConverter.ToInt64(_obj, 0);
if (!allowNegativeValue)
{
_num = (_num & ~(1L << 63));
}
return _num;
}
}
Any help explaining it would be appreciated

<< is the bitshift operator 1L << 63 Results in shifting the 1 left 63 places or 1 followed by 63 0s
~ is i believe bitwise not, So this would apply to the above and result in 0 followed by 63 1s
& is bitwise and, it results in applying the and operation bitwise to both operands
Ultimately this appears to be filtering it down to 63 bits of data, since any higher bits will be zeroed out due to the and
The reason this works to force positive, is because typically the highest bit(#64 in your case) is used as a sign bit in most notations, and this code just essentially 0s it out, thus forcing it to be not negative, i.e positive

a = ~(1L << 63) = ~0x1000000000000000 = 0x7fffffffffffffff
so m &= a clears the highest bit of m, thus ensuring it's positive, assuming the two's complement encoding of signed integers is used.

Related

Conversion an Int to two Shorts returns padded data / negative values

I have a simple piece of code to convert an Int to two shorts:
public static short[] IntToTwoShorts(int a)
{
byte[] bytes = BitConverter.GetBytes(a);
return new short[] { BitConverter.ToInt16(bytes, 0), BitConverter.ToInt16(bytes, 2) };
}
If I pass in 1851628330 (‭0x6E5D 9B2A‬) the result is:
{short[2]}
[0]: -25814
[1]: 28253
The problem is that -25814 is 0xFFFF 9B2A
I've tried various flavours including bit shifting. What's going on? That result isn't a short, and doesn't have 16 bits!
The trick is to use ushort when combining back two short into int:
public static short[] IntToTwoShorts(int a) {
unchecked {
return new short[] {
(short) a,
(short) (a >> 16)
};
}
}
public static int FromTwoShorts(short[] value) {
unchecked {
if (null == value)
throw new ArgumentNullException("value");
else if (value.Length == 1)
return (ushort)value[0]; // we don't want binary complement here
else if (value.Length != 2)
throw new ArgumentOutOfRangeException("value");
return (int)((value[1] << 16) | (ushort)value[0]); // ... and here
}
}
The cause of the unexpected behaviour is that negative numbers (like -25814) are represented as binary complements and so you have the same value (-25814) represented differently in different integer types:
-25814 == 0x9b2a // short, Int16
-25814 == 0xffff9b2a // int, Int32
-25814 == 0xffffffffffff9b2a // long, Int64
Some tests
int a = 1851628330;
short[] parts = IntToTwoShorts(a);
Console.WriteLine($"[{string.Join(", ", parts)}]");
Console.WriteLine($"{FromTwoShorts(parts)}");
Console.WriteLine($"{FromTwoShorts(new short[] { -25814 })}");
Console.WriteLine($"0x{FromTwoShorts(new short[] { -25814 }):X}");
Outcome:
[-25814, 28253]
1851628330
39722
0x9B2A
I would approach the problem with something like this:
public static short[] IntToTwoShorts(int a)
{
short retVar[2];
//Upper 16 byte masked with 0x0000FFFF
retVar[0] = (short) (a >> 16) & (65535);
//Lower 16 byte masked with 0x0000FFFF
retVar[1] = (short) (a >> 0) & (65535);
return retVar;
}
The problem isn't with the code (although there may be more efficient ways to do split integers). By attempting to represent an int as two signed 16 bit shorts, you now need to consider that the sign bit could be present in both shorts. Hence the comment that ushort[] would be a more appropriate choice of representation of the two 16 bit values.
The problem seems to be with the understanding of why a 4 byte signed integer (DWORD) can't be effectively represented in two 2 byte signed shorts (WORD)s.
The problem is that -25814 is 0xFFFF 9B2A
This isn't true - you've represented -25814 as a short, so it can't possibly be 0xFFFF 9B2A - that's a 32 bit representation. Its 16 bit representation is just 9B2A.
If you open up the Calculator on Windows, and set the mode to programmer, and tinker with the HEX and DEC bases, and then flipping between DWORD and WORD representations of the values, you should see that the 16 bit values you've extracted from the 32 bit int are correctly represented (provided that you understand the representation):
Your original 32 bit Integer (DWORD) is 1851628330:
The high word 28253 doesn't have the sign bit set, so you seem satisfied with the conversion to 6E5D:
However, if the low word is interpreted as a signed short, then you'll find that it's bit sign is set, so hence it reported as a negative value. However, the representation (bits, and hex) does correctly represent the last 16 bits of your original 32 bit int.

Interlacing two binary numbers together in Arduino C

So I've come across a strange need to 'merge' two numbers:
byte one;
byte two;
into an int three; with the first bit being the first bit of one, the second bit being the first bit of two, the third being the second bit of one and so on.
So with these two numbers:
01001000
00010001
would result in
0001001001000010
A more didatic illustration of the interlacing operation:
byte one = 0 1 0 0 1 0 0 0
byte two = 0 0 0 1 0 0 0 1
result = 00 01 00 10 01 00 00 10
UPDATE: Sorry misread your question completely.
The following code should do:
public static int InterlacedMerge(byte low, byte high)
{
var result = 0;
for (var offset = 0; offset < 8; offset++)
{
var mask = 1 << offset;
result |= ((low & mask) | ((high & mask)) << 1) << offset;
}
return result;
}
I am not, by any means, very smart when it comes to bit twiddling so there probably is a more efficient way to do this. That said, I think this will do the job but I haven't tested it, so make sure you do.
P.D: There are some unnecessary parenthesis in the code but I'm never sure about bitwise operators precedence so I find it easier to read the way its written.
UPDATE2: Here is the same code a little more verbose to make it easier to follow:
public static int InterlacedMerge(byte low, byte high)
{
var result = 0;
for (var offset = 0; offset < 8; offset++)
{
//Creates a mask with the current bit set to one: 00000001,
//00000010, 00000100, and so on...
var mask = 1 << offset;
//Creates a number with the current bit set to low's bit value.
//All other bits are 0
var lowAndMask = low & mask;
//Creates a number with the current bit set to high's bit value.
//All other bits are 0
var highAndMask = high & mask;
//Create a merged pair where the lowest bit is the low 's bit value
//and the highest bit is high's bit value.
var mergedPair = lowAndMask | (highAndMask << 1);
//Ors the mergedPair into the result shifted left offset times
//Because we are merging two bits at a time, we need to
//shift 1 additional time for each preceding bit.
result |= mergedPair << offset;
}
return result;
}
#inbetween answered while I was writing this; similar solution, different phrasing.
You'll have to write a loop. You'll test one bit in each of the two inputs. You'll set a bit in an output for each input. You'll shift all three values one place. Maybe something like this (untested):
#define TOPBIT 32768
for /* 16 times */
if ( value1 & 1 ) out |= TOPBIT;
out >>= 1;
if ( value2 & 1 ) out |= TOPBIT;
out >>= 1;
b1 >>= 1;
b2 >>= 1;

C# How to remove the n-th bit in integer?

I am trying to find a way to remove a bit from an integer. The solution must not use string operations.
For example, I have the number 27, which is 11011 in binary.
I want to remove the third bit so it leaves me with 1011.
Or we have 182 (10110110), remove the 6th bit so the result is 1110110 (which is 118). I am trying to think of the algorithm how to do that, but so far no luck, and I can't find useful information on the internet.
I know how to use bitwise operators and how to extract or manipulate bits in integers (change values, exchange values etc), but I don't know how to 'remove' a certain bit.
I am not looking for code, just the logic of the operation. If anyone could help me, that would be awesome!
Regards,
Toni
No problem, just decompose the number into the "upper part" and the "lower part", and put them together without the middle bit that now disappeared.
Not tested:
uint upper = x & 0xFFFFFFF0;
uint lower = x & 7;
return (upper >> 1) | lower;
More generally: (also not tested)
uint upper = x & (0xFFFFFFFE << n);
uint lower = x & ((1u << n) - 1);
return (upper >> 1) | lower;
In order to do this you need two bit masks and a shift.
The first bit mask gives you the portion of the number above bit n, exclusive of the n-th bit. The mask is constructed as follows:
var top = ~((1U<<(n+1))-1); // 1111 1111 1000 000, 0xFF80
The second bit mask gives you the portion of the number below bit n, exclusive of the n-th bit:
var bottom = (1U<<n)-1; // 0000 0000 0011 1111, 0x003F
Comments above show the values for your second example (i.e. n == 6)
With the two masks in hand, you can construct the result as follows:
var res = ((original & top)>>1) | (original & bottom);
Demo.
You could use the following approach:
int value = 27;
string binary = Convert.ToString(value, 2);
binary = binary.Remove(binary.Length-3-1,1); //Remove the exact bit, 3rd in this case
int newValue = Convert.ToInt32(binary, 2);
Console.WriteLine(newValue);
Hope it helps!
int Place = 7;
int TheInt = 182;
string binary = Convert.ToString(TheInt, 2);
MessageBox.Show(binary.Remove(binary.Length - Place, 1));
Here is a version that needs slightly fewer operations than the solution by harold:
x ^ (((x >> 1) ^ x) & (0xffffffff << n));
The idea is that below n, bits are xored with zero, leaving them unchanged, while from n and above the two x xored cancel each other out, leaving x >> 1.
int a = 27;//int= 4byte equal to 32 bit
string binary = "";
for (int i = 0; i < 32; i++)
{
if ((a&1)==0)//if a's least significant bit is 0 ,add 0 to str
{
binary = "0" + binary;
}
else//if a's least significant bit is 1 ,add 1 to str
{
binary = "1" + binary;
}
a = a >> 1;//shift the bits left to right and delete lsb
//we are doing it for 32 times because integer have 32 bit.
}
Console.WriteLine("Integer to Binary= "+binary);
//Now you can operate the string(binary) however you want.
binary = binary.Remove(binary.Length-4,1);//remove 4st bit from str

Defining a bit[] array in C#

currently im working on a solution for a prime-number calculator/checker. The algorythm is already working and verry efficient (0,359 seconds for the first 9012330 primes). Here is a part of the upper region where everything is declared:
const uint anz = 50000000;
uint a = 3, b = 4, c = 3, d = 13, e = 12, f = 13, g = 28, h = 32;
bool[,] prim = new bool[8, anz / 10];
uint max = 3 * (uint)(anz / (Math.Log(anz) - 1.08366));
uint[] p = new uint[max];
Now I wanted to go to the next level and use ulong's instead of uint's to cover a larger area (you can see that already), where i tapped into my problem: the bool-array.
Like everybody should know, bool's have the length of a byte what takes a lot of memory when creating the array... So I'm searching for a more resource-friendly way to do that.
My first idea was a bit-array -> not byte! <- to save the bool's, but haven't figured out how to do that by now. So if someone ever did something like this, I would appreciate any kind of tips and solutions. Thanks in advance :)
You can use BitArray collection:
http://msdn.microsoft.com/en-us/library/system.collections.bitarray(v=vs.110).aspx
MSDN Description:
Manages a compact array of bit values, which are represented as Booleans, where true indicates that the bit is on (1) and false indicates the bit is off (0).
You can (and should) use well tested and well known libraries.
But if you're looking to learn something (as it seems to be the case) you can do it yourself.
Another reason you may want to use a custom bit array is to use the hard drive to store the array, which comes in handy when calculating primes. To do this you'd need to further split addr, for example lowest 3 bits for the mask, next 28 bits for 256MB of in-memory storage, and from there on - a file name for a buffer file.
Yet another reason for custom bit array is to compress the memory use when specifically searching for primes. After all more than half of your bits will be 'false' because the numbers corresponding to them would be even, so in fact you can both speed up your calculation AND reduce memory requirements if you don't even store the even bits. You can do that by changing the way addr is interpreted. Further more you can also exclude numbers divisible by 3 (only 2 out of every 6 numbers has a chance of being prime) thus reducing memory requirements by 60% compared to plain bit array.
Notice the use of shift and logical operators to make the code a bit more efficient.
byte mask = (byte)(1 << (int)(addr & 7)); for example can be written as
byte mask = (byte)(1 << (int)(addr % 8));
and addr >> 3 can be written as addr / 8
Testing shift/logical operators vs division shows 2.6s vs 4.8s in favor of shift/logical for 200000000 operations.
Here's the code:
void Main()
{
var barr = new BitArray(10);
barr[4] = true;
Console.WriteLine("Is it "+barr[4]);
Console.WriteLine("Is it Not "+barr[5]);
}
public class BitArray{
private readonly byte[] _buffer;
public bool this[long addr]{
get{
byte mask = (byte)(1 << (int)(addr & 7));
byte val = _buffer[(int)(addr >> 3)];
bool bit = (val & mask) == mask;
return bit;
}
set{
byte mask = (byte) ((value ? 1:0) << (int)(addr & 7));
int offs = (int)addr >> 3;
_buffer[offs] = (byte)(_buffer[offs] | mask);
}
}
public BitArray(long size){
_buffer = new byte[size/8 + 1]; // define a byte buffer sized to hold 8 bools per byte. The spare +1 is to avoid dealing with rounding.
}
}

FlagsAttribute Enum problems

So I'm building an MSNP (windows live messenger) client. And I've got this list of capabilities
public enum UserCapabilities : long
{
None = 0,
MobileOnline = 1 << 0,
MSN8User = 1 << 1,
RendersGif = 1 << 2,
....
MsgrVersion7 = 1 << 30,
MsgrVersion8 = 1 << 31,
MsgrVersion9 = 1 << 32,
}
full list here http://paste.pocoo.org/show/383240/
The server sends each users capabilities to the client as a long integer, which I take and cast it to UserCapabilities
capabilities = Int64.Parse(e.Command.Args[3]);
user._capabilities = (UserCapabilities)capabilities;
This is fine, and with atleast one user (with a capability value of 1879474220), I can do
Debug.WriteLine(_msgr.GetUser(usr).Capabilities);
and this will output
RendersGif, RendersIsf, SupportsChunking, IsBot, SupportsSChannel, SupportsSipInvite, MsgrVersion5, MsgrVersion6, MsgrVersion7
But with another user, who has the capability value of (3055849760), when I do the same, I just get the same number outputted
3055849760
What I would like to be seeing is a list of capabilities, as it is with the other user.
I'm sure there is a very valid reason for this happening, but no matter how hard I try to phrase the question to Google, I am not finding an answer.
Please help me :)
The definition of the shift operators means that only the 5 least significant bits are used for 32-bit numbers and only the first 6 bits for 64-bit; meaning:
1 << 5
is identical to
1 << 37
(both are 32)
By making it:
MsgrVersion9 = 1L << 32
you make it a 64-bit number, which is why #leppie's fix works; otherwise the << is considered first (and note that 1<<32 is identical to 1<<0, i.e. 1), and then the resulting 1 is converted to a long; so it is still 1.
From §14.8 in the ECMA spec:
For the predefined operators, the number of bits to shift is computed as follows:
When the type of x is int or uint, the shift count is given by the low-order five bits of count. In other words, the shift count is computed from count & 0x1F.
When the type of x is long or ulong, the shift count is given by the low-order six bits of count. In other words, the shift count is computed from count & 0x3F.
If the resulting shift count is zero, the shift operators simply return the value of x.
Shift operations never cause overflows and produce the same results in checked and unchecked context
The problem could be with arithmetic overflow.
Specifically at:
MsgrVersion8 = 1 << 31,
MsgrVersion9 = 1 << 32,
I suggest you make it:
MsgrVersion8 = 1L << 31,
MsgrVersion9 = 1L << 32,
To prevent accidental overflow.
Update:
Seems likely as the smaller number on 'touches' 31 bits, while the bigger one 'touches' 32 bits.

Categories