What is the Bitewise AND doing here - sql

I have never used Bitewise AND in my life. I have researched this operator but it still eludes me as to what it exactly does. So, I will ask with some code I just came across, what is the Bitwise And doing here:
CASE
WHEN (ft.Receiver_Status & 2) = 2 THEN '3D'
WHEN (ft.Receiver_Status & 1) = 1 THEN '2D'
WHEN (ft.Receiver_Status & 32) = 32 THEN 'Invalid' -- AR 220312
ELSE 'None'
Is it enforcing the same datatype, such as smallint converts to int before comparing the value of Receiver_Status?

ft.Receiver_Status & 1: 1 is 20, so it is pulling out the value of the bit at position 0.
ft.Receiver_Status & 2: 2 is 21, so it is pulling out the value of the bit at position 1.
ft.Receiver_Status & 32: 32 is 25, so it is pulling out the value of the bit at position 5.
Note that, for example, the = 32 in (ft.Receiver_Status & 32) = 32 is actually redundant. This could instead be (ft.Receiver_Status & 32) != 0 because all you're interested in is whether that bit is a 0 or a 1.

The bitwise AND checks to see whether a particular bit is set. It appears ft.Receiver_Status is an integer which stores various flags in different bits.
1 in binary is 00001 so ft.Receiver_Status & 1 is checking to see if the first bit is set.
2 in binary is 00020 so ft.Receiver_Status & 1 is checking to see if the second bit is set.
32 in binary is 10000 so ft.Receiver_Status & 32 is checking to see if the fifth bit is set.
To see precisely how this works, the result of the AND operation will be the bit at position n will be 1 f and only if the bit at position n in both the first and the second number is 1. Consider the following binary numbers:
011010001 (209)
000010000 ( 32)
---------------
000010000 ( 32)
And alternatively,
011001001 (201)
000010000 ( 32)
---------------
000000000 ( 0)

(something & constant) == constant (where constant is a power of two) is a way of ensuring that the bit defined in constant is set. Consider your first case. All of the bits in 2 aren't set except for the second bit, so we know the rest will be zero. If the second bit is not set in Receiver_Status then the result will be zero, if it is set, that bit will be one and the result will be two, the same as the bit mask.
It could also be written as (ft.Receiver_Status & 2) > 0 to avoid repeating the bit mask in each case.

You should read about bit flags. That's the way to check, if particular bit within a bigger data type (e.g. byte) is set to 1 or not.
Example:
Consider having a bite with following bits content: 00110101. You'd like to check the fifth position. You need to change all other bits to 0 and check, if that one is 1 or 0. To do that, perform bitewise AND with 2^4:
00110101
00010000 &
--------
00010000

To give a concrete example with all these other great answers, if Receiver_Flags were 3, the 1 and 2 bits are on. Likewise, if it were 34, the 2 and 32 bits are on.
A lot of times an enum is used to set these fields. Consider this enum:
public enum Flags
{
ThreeD = 1,
TwoD = 2,
Invalid = 3
}
You might set the value like this:
Receiver_Flags = Flags.ThreeD | Flags.TwoD
and the value would be 3. In that case the 1 and 2 bits would be on.

This is very similar to Enum.HasFlag. Here's one way to implement that for a Test enum:
static bool HasFlag(Test flags, Test flag)
{
return (flags & flag) != 0;
}
Basically, (ft.Receiver_Status & 32) = 32 checks if the fifth bit is 1 or 0.

Related

I want to know the specific reason why we have take those 256,.. numbers in the conversion below

Projected code is used to convert a date into integer and vice-versa. I want to know the reason why here we have used this specific hexadecimal codes and the number series to get back the date from int. If there is an article about this code sample it would also help me understand this code actually.
I have tried online Hex to Decimal conversion for this codes and found its a 256^1,256^2... even though trying not able to find the exact reason.
declare #dDate date = '2017-10-12'
declare #iDate int = 0
select #iDate = ( (datepart(year,#dDate)*65536 | datepart(month,#dDate)*256 | datepart(dd,#dDate)))
select (#iDate&0xfff0000)/65536 --year
select (#iDate&0xff00)/256 --Month
select (#iDate&0xff) --Date
& is an operator doing bitwise AND. "|" is bitwise OR. See here and here. Also see here for an explanation on using bitwise AND/OR to store multiple number values in a single number column.
This part:
#iDate&0xfff0000
will "mask", or eliminate/replace-with-zeros, the portion of iDate that isn't from 256^2. Then you divide by 65536 -- which is simply reversing the original math of multiplying the year by 65536.
If the concept of bitwise AND is foreign, I'll give an example that DOESN'T WORK in decimal. Bitwise AND converts the whole thing to binary and then masks things (like IP subnetting, if you're familiar with that).
Anyway, consider a decimal number 20171012. If such a thing as a decimal-wise AND existed, it could look like 20171012&11110000. The "1" places are "keepers" and the "0" places are "throw-aways". If you stack them vertically, the result is to keep the values with a "1" beneath them and replace the values with a "0" beneath them with a "0".
number 20171012
dec-wise AND 11110000
result 20170000
now the result isn't 2017, so you'd have to divide by 10000 to get 2017.
For 20171012&1100 you have to use implied leading zeros:
number 20171012
dec-wise AND 00001100
result 1000
I probably would have converted to int by adding the year*10000 and month * 100 and day. Reverting back I would use a combination of integer division and MOD. But I think the bitwise AND is perhaps a bit more elegant (particularly for getting the month).
Based on your comment, I will include how I have converted dates to int and reverted back:
declare #dDate date = '2017-10-12'
declare #iDate int
set #iDate = year(#dDate) * 10000 + month(#dDate) * 100 + day(#dDate)
select #iDate
select 'year', #iDate/10000 -- basic integer division provides the year
select 'month', (#iDate % 10000)/100 -- combine modulo and integer division to get the month
select 'day', #iDate % 100 -- basic modulo arithmetic provides the day
returns:
20171012
year 2017
month 10
day 12
This is bit manipulation.
Bit Shifting
Decimal 3 = Binary 11
If we do a left shift (<<) 4 bits in 3 it will become 48 which is equal to binary 110000 <- 4 zero bits added due to left shift
But since we don't have bit shifting operators in T-SQL therefore we can do the math.
Left Shifting of n bits in number x = x * 2^n
Therefore, multiple a number with 256 is actually left shift 8 bits from that number (2^8 = 256).
Later on when you do bitwise OR between 2 numbers they actually "concatenate" the bits up.
For example, you need to concatenate 2 binary numbers, (3) 11 and (2) 10, the resultant number should be 1110 = 14
So first we'll do 2 left shift in 3 = 3 * 2^2 = 12 and then we will do bitwise OR this number with the next number
12 = 1100
2 = 0010
OR
---------------
14 = 1110
Your example is actually saving the whole date in an integer variable which is actually efficient way of saving a date.

Incrementing part of bit mask

Given enum:
typedef NS_OPTIONS(NSUInteger, BREBreathingProgram) {
BREBreathingProgramPaceSlowest = 0,
BREBreathingProgramPaceSlow = 1,
BREBreathingProgramPaceMedium = 2,
BREBreathingProgramPaceFast = 3,
BREBreathingProgramPaceFastest = 4,
BREBreathingProgramExcludeHold = 1 << 3,
};
To increment BreathingProgramPace I perform the following calculation:
breathingProgram = ((breathingProgram >> 3) & 1) << 3 | (breathingProgram & 3) + 1;
Is this the simplest way to do this?
Based on your 2nd comment to this answer I am rewriting the answer.
You have setup your enum so the first 3 bits represent a single value for the pace. You can have a value up to 7.
The fourth bit represents your "hold".
You wish to have some pace value and also some other bits set. You then wish to be able to increment that pace while keeping the other bits as they are.
This is simple.
breathingProgram++;
A simple increment is all you need. Example. Lets say your pace is set to "Slow" and the "hold" bit is set. This gives a value of 9 (1 for "slow" and 8 for "hold").
Now you wish to increment the pace to "medium". Simply incrementing from 9 to 10 does this.
While this works there is the risk that you could over increment the value and start messing with the flags.
A safer (and more complicated) way would be:
breathingProgram = (breathingProgram & 0xF8) | (((breathingProgram & 0x07) + 1) & 0x07);
This ensures that you can't do the increment past the allotted "pace" values and into the flags area. This would actually wrap the "pace" value back to zero if you went too far.

What is the most elegant way to pick a random value from a set defined in NS_OPTION in objective-c?

I have an NS_OPTION that I'm defining as such :
typedef NS_OPTIONS(NSInteger, PermittedSize) {
SmallSize = 1 << 0,
MediumSize = 1 << 1,
LargeSize = 1 << 2
};
And later I set the values I need :
PermittedSize size = SmallSize | MediumSize;
I'm using it to randomly generate an various objects of small and medium sizes(duh) for a particular level of a game.
What is the best way to go about selecting which size of an object to generate? Meaning, I'd like to choose randomly for each object I'm generating whether it will be one of the 2 options allowed (small and medium in this case). Normally I would use an arc4random function with the range of numbers I need - but in this case, how can it be done with bits? (and then mapped back to the values of the PermittedSize type?
Use the result from arc4random to determine the amount of bit shifting you want to do. Something like this:
int bitShiftAmount = arc4random_uniform(numberOfPermittedSizes);
PermittedSize size = 1 << bitShiftAmount;
You are still working with integers. SmallSize is 1. MediumSize is 2. And LargeSize is 4.
So pick a random number from 1 to 3. 1 is small, 2 is medium, 3 is both.
Once you have a random number, assign it.
NSInteger val = arc4random_uniform(3) + 1; // give 1-3
PermittedSize size = (PermittedSize)val;

I'm new to visual basic and trying to understand how to set individual bits in a byte [closed]

It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 10 years ago.
Hi, I am new to Visual Basic, I have a project where I need to be able to manipulate individual bits in a value.
I need to be able to switch these bits between 1 and 0 and combine multiple occurrences of bits into one variable in my code.
Each bit will represent a single TRUE / FALSE value, so I'm not looking for how to do a single TRUE / FALSE value in one variable, but rather multiple TRUE / FALSE values in one variable.
Can someone please explain to me how I can achieve this please.
Many thanks in advance.
Does it have to be exactly one bit?
Why don't you just use the actual built in VB data type of Boolean for this.
http://msdn.microsoft.com/en-us/library/wts33hb3(v=vs.80).aspx
It's sole reason for existence is so you can define variables that have 2 states, true or false.
Dim myVar As Boolean
myVar = True
myVar = Flase
if myVar = False Then
myVar = True
End If
UPDATE (1)
After reading through the various answers and comments from the OP I now understand what it is the OP is trying to achieve.
As others have said the smallest unit one can use in any of these languages is an 8 bit byte. There is simply no order of data type with a smaller bit size than this.
However, with a bit of creative thinking and a smattering of binary operations, you can refer to the contents of that byte as individual bits.
First however you need to understand the binary number system:
ALL numbers in binary are to the power of two, from right to left.
Each column is the double of it's predecessor, so:
1 becomes 2, 2 becomes 4, 4 becomes 8 and so on
looking at this purely in a binary number your columns would be labelled thus:
128 64 32 16 8 4 2 1 (Remember it's right to left)
this gives us the following:
The bit at position 1 = 1;
The bit at position 2 = 2;
The bit at position 3 = 4;
The bit at position 4 = 8;
and so on.
Using this method on the smallest data type you have (The byte) you can pack 8 bit's into one value. That is you could use one variable to hold 8 separate values of 1 or 0
So while you cannot go any smaller than a byte, you can still reduce memory consumption by packing 8 values into 1 variable.
How do you read and write the values?
Remember the column positions? well you can use something called Bit Shifting and Bit masks.
Bit Shifting is the process of using the
<<
and
>>
operators
A shifting operation takes as a parameter the number of columns to shift.
EG:
Dim byte myByte
myByte = 1 << 4
In this case the variable 'myByte' would become equal to 16, but you would have actually set bit position 5 to a 1, if we illustrate this, it will make better sense:
mybyte = 0 = 00000000 = 0
mybyte = 1 = 00000001 = 1
mybyte = 2 = 00000010 = (1 << 1)
mybyte = 4 = 00000100 = (1 << 2)
mybyte = 8 = 00001000 = (1 << 3)
mybyte = 16 = 00010000 = (1 << 4)
the 0 through to 16 if you note is equal to the right to left column values I mentioned above.
given what Iv'e just explained then, if you wanted to set bits 5, 4 and 1 to be equal to 1 and the rest to be 0, you could simply use:
mybyte = 25(16 + 8 + 1) = 00011001 = (1 << 4) + (1 << 3) + 1
to get your bits back out, into a singleton you just bit shift the other way
retrieved bit = mybyte >> 4 = 00000001
Now there is unfortunately however one small flaw with the bit shifting method.
by shifting back and forth you are highly likely to LOOSE information from any bits you might already have set, in order to prevent this from happening, it's better to combine your bit shifting operations with bit masks and boolean operations such as 'AND' & 'OR'
To understand what these do you first need to understand simple logic principles as follows:
AND
Output is one if both the A and B inputs are 1
Illustrating this graphically
A B | Output
-------------
0 0 | 0
0 1 | 0
1 0 | 0
1 1 | 1
As you can see if a bit position in our input number is a 1 and the same position in our input number B is 1, then we will keep that position in our output number, otherwise we will discard the bit and set it to a 0, take the following example:
00011001 = Bits 5,4 and 1 are set
00010000 = Our mask ONLY has bit 5 set
if we perform
00011001 AND 0010000
we will get a result of
00010000
which we can then shift down by 5
00010000 >> 5 = 00000001 = 1
so by using AND we now have a way of checking an individual bit in our byte for a value of 1:
if ((mybyte AND 16) >> 1) = 1 then
'Bit one is set
else
'Bit one is NOT set
end if
by using different masks, with the different values of 2 in the right to left columns as shown previously, we can easily extract different singular values from our byte and treat them as a simple bit value.
Setting a byte is just as easy, except you perform the operation the opposite way using an 'OR'
OR
Output is one if either the A or B inputs are 1
Illustrating this graphically
A B | Output
-------------
0 0 | 0
0 1 | 1
1 0 | 1
1 1 | 1
eg:
00011001 OR 00000100 = 00011101
as you can see the bit at position 4 has been set.
To answer the fundamental question that started all this off however, you cannot use a data type in VB that has any resolution less than 1 byte, I suspect if you need absolute bit wise accuracy I'm guessing you must be writing either a compression algorithm or some kind of encryption system. :-)
01010100 01110010 01110101 01100101, is the string value of the word "TRUE"
What you want is to store the information in a boolean
Dim v As Boolean
v = True
v = False
or
If number = 84 Then ' 84 = 01010100 = T
v = True
End If
Other info
Technicaly you can't store anything in a bit, the smallest value is a char which is 8 bit. You'll need to learn how to do bitwise operation. Or use the BitArray class.
VB.NET (nor any other .NET language that I know of) has a "bit" data type. The smallest that you can use is a Byte. (Not a Char, they are two-bytes in size). So while you can read and convert a byte of value 84 into a byte with value 1 for true, and convert a byte of value 101 into a byte of value 0 for false, you are not saving any memory.
Now, if you have a small and fixed number of these flags, you CAN store several of them in one of the integer data types (in .NET the largest integer data type is 64 bits). Or if you have a large number of these flags you can use the BitArray class (which uses the same technique but backs it with an array so storage capacity is greater).

What is Lazy Binary Search?

I don't know whether the term "Lazy" Binary Search is valid, but I was going through some old materials and I just wanted to know if anyone can explain the algorithm of a Lazy Binary Search and compare it to a non-lazy Binary Search.
Let's say, we have this array of numbers:
2, 11, 13, 21, 44, 50, 69, 88
How to look for the number 11 using a Lazy Binary Search?
Justin was wrong.
The common binarySearch algorithm first checks whether the target is equal to current middle entry before proceeding to the left or right halves if required. Lazy binarySearch algorithm postpones the equality check until the very end.
algorithm lazyBinarySearch(array, n, target)
left<-0
right<-n-1
while (left<right) do
mid<-(left+right)/2
if(target>array[mid])then
left<-mid+1
else
right<-mid
endif
endwhile
if(target==array[left])then
display "found at position", left
else
display "not found"
endif
In your case, in an array,
2 11 13 21 44 50 69 88
and you want to search for 11
First we do a trace of common binary search,
index 0 1 2 3 4 5 6 7
2 11 13 21 44 50 69 88
left mid right
First while loop:
left <= right, we enter the first while loop. We calculated the mid index by (0+7)/2=3.5=3 by integer division, mid = 3. straight away we check if target 11 is equal to the mid index entry, 11 != 21, then we decide whether to go left or right, we finds out 11 < 21, should go left. left index remains unchanged, right index becomes mid index -1, right = 3 - 1 = 2. Done this step.
Second while loop:
left <= right, 0 <= 2, we enter the seond while loop. Mid index is recalcuated: (0+2)/2=1, mid = 1. At once we do the equality check, target 11 is the same as the index 1 entry, 11 == 11. We found this entry, leaving behind all the left right mid indexes (don't care) and breaks out the while loop, return index 1.
Now we trace this search by lazy binazySearch algorithm, initial array with left/right indexes set up the same as previous.
First while loop:
left < right, we enter the first while loop. Mid index is calculated as the same above = 3. Instead of doing an equality check in common binarySearch we do a comparison with the mid index entry this time. And the comparison only checks if our target 11 is greater than the mid index entry, leaving whether they equal or not to the very end outside the while loop. So we find out 11 < 21, right index is reset to the mid index, right = 3. Done this step.
Second while loop:
left < right, 0 < 3, we enter the second while loop. mid index is recalculated as mid = (0+3)/2 = 1 by integer division. Again we do a comparison with mid index entry 11, we realise it's not greater than mid index entry. We fall into the else part of the while loop and reset the right index to be mid index, right = 1. Done this step.
Third while loop:
left < right, 0 < 1, this time we have to re-enter the while loop again since it still satisfies the while condition. Mid index becomes (0+1)/2=0, mid = 0. After comparing target 11 with mid index entry 2 we found out it's greater than it (11 > 2), left index is reset to mid + 1, left = 0 + 1 = 1. Done this step.
With left index = 1 and right index = 1, left = right, while loop condition is no longer satisfied, so there's no need to re-enter. We fall into the if part down below. Target 11 equals left index entry 11, we found the target and returns left index 1.
As you can see, lazy binarySearch does one more while loop step to finally realise the index is actually 1. And this is how the word "postpones the equality check" means in the definition I mentioned in the very beginning. Clearly the lazy binarySearch algorithm does more things than common binarySearch before reaching the program termination. And the term "lazy" is reflected in the time of when to check the target equals the mid index entry.
However lazy binarySearch is more preferable to use under some other circumstances, but it's not in the context of this case.
(The reasoning part of the algorithm is done by me, anyone wishes to copy please do credit)
source: "Data Structures Outside In With Java" by Sesh Venugopal, Prentice Hall
As far as I am aware "Lazy binary search" is just another name for "Binary search".