short way of ORing all flags - go

With the following:
const (
Flag1 = 0
Flag2 = uint64(1) << iota
Flag3
Flag4
Flag5
)
is there a shorter/better way of doing, I want to OR them all:
const FlagAll = Flag1 | Flag2 | Flag3 | Flag4 | Flag5

Since all your flags contain a single 1 bit, shifting the bit to the left, FlagAll would be the next in the line but subtract 1:
const (
Flag1 = 0
Flag2 = uint64(1) << iota
Flag3
Flag4
Flag5
FlagAll = uint64(1)<<iota - 1
)
Testing it:
fmt.Printf("%08b\n", Flag1)
fmt.Printf("%08b\n", Flag2)
fmt.Printf("%08b\n", Flag3)
fmt.Printf("%08b\n", Flag4)
fmt.Printf("%08b\n", Flag5)
fmt.Printf("%08b\n", FlagAll)
This will output (try it on the Go Playground):
00000000
00000010
00000100
00001000
00010000
00011111
Note that you get the same value if you left shift the last constant and subtract 1:
const FlagAll2 = Flag5<<1 - 1
But this requires to explicitly include the last constant (Flag5) while the first solution does not require it (you may add further flags like Flag6, Flag7..., and FlagAll will be right value without changing it).

Related

Get value of one bit from 32 bits

How do you apply a mask to get only one bit after you shift right? Does it depend on how many positions you shifted right?
In a 32 bit structure I'm trying to get the value of the 9th bit and the 10th bit.
x := uint32(11537664)
0000 0000 1011 0000 0000 1101 0000 0000
^^
So for the 9th bit, if I shift right 23 bits I need to mask one byte? That seems to isolate the 9th bit because I'm getting a value of 1.
(x >> 23) & 0xff
9th bit...should be 1... looks ok.
00000000000000000000000000000001
0x1
So to get the 10th bit which should be 0 I am shifting one less bit which does make 0 all the way to the right. But there is a 1 after it which needs to be masked. I figured 1 byte plus 1 bit for the mask but I'm still seeing the the bit in position two so that can't be right.
(x >> 22) & 0x1ff
10th bit... should be 0, but this shift and mask does not look correct.
00000000000000000000000000000010
^ This bit I don't want.
0x2
Link to example:
https://play.golang.org/p/zqofCAAKDZz
package main
import (
"fmt"
)
func bin(i uint32) {
fmt.Printf("%032b\n", i)
}
func hex(i uint32) {
fmt.Printf("0x%x\n", i)
}
func show(i uint32) {
bin(i)
hex(i)
fmt.Println()
}
func main() {
x := uint32(11537664)
fmt.Println("Data")
show(x)
fmt.Println("First 8 bits.")
show(x >> 24)
fmt.Println("9th bit...should be 1")
show((x >> 23) & 0xff)
fmt.Println("10th bit... should be 0")
show((x >> 22) & 0x1ff)
}
After the shift you get a number being 0b10, and you only need the lowest bit. So why are you masking with 0x1ff? That has 9 one bits, that will leave the lowest 9 bits unchanged (unmasked).
Instead mask with 0b01 = 0x01. That only leaves the lowest bit, and zeroes all others:
show((x >> 22) & 0x01)
Try it on the Go Playground.
Also note that if you just want to test if a certain bit is one or zero, you don't neccessarily have to shift. Masking by a proper bitmask that contains a single one at the certain position is enough. You may compare the masking result with zero.
The proper bitmask for testing the nth bit is simply 1<<n (where bits are zero indexed). The 2 bits you want to test are the 22. and 23. bits.
See this example:
x := uint32(11537664)
fmt.Printf("x : %032b\n", x)
fmt.Println()
const mask22 = 1 << 22
fmt.Printf("mask22 : %032b\n", mask22)
fmt.Printf("22. bit: %032b %t\n", x&mask22, x&mask22 != 0)
fmt.Println()
const mask23 = 1 << 23
fmt.Printf("mask23 : %032b\n", mask23)
fmt.Printf("23. bit: %032b %t\n", x&mask23, x&mask23 != 0)
It outputs (try it on the Go Playground):
x : 00000000101100000000110100000000
mask22 : 00000000010000000000000000000000
22. bit: 00000000000000000000000000000000 false
mask23 : 00000000100000000000000000000000
23. bit: 00000000100000000000000000000000 true

Golang Left/Right shift behaviour for signed numbers

Can someone please explain the left/right shift behaviour in Golang. Please refer the sample code here: https://play.golang.org/p/7vjwCbOEkw
package main
import (
"fmt"
)
func main() {
var lf int8 = -3
fmt.Printf("-3 : %08b\n", lf)
fmt.Printf("<<1: %08b\n", lf<<1)
fmt.Printf("<<2: %08b\n", lf<<2)
fmt.Printf("<<3: %08b\n", lf<<3)
fmt.Printf("<<4: %08b\n", lf<<4)
fmt.Printf("<<5: %08b, %d\n", lf<<5, lf<<5)
fmt.Printf("<<6: %08b, %d\n", lf<<6, lf<<6)
fmt.Printf("<<7: %08b, %d\n", lf<<7, lf<<7)
fmt.Printf("<<8: %08b, %d\n", lf<<8, lf<<8)
fmt.Printf("<<9: %08b, %d\n", lf<<9, lf<<9)
}
-3 : -0000011
<<1: -0000110
<<2: -0001100
<<3: -0011000
<<4: -0110000
<<5: -1100000, -96
<<6: 01000000, 64
<<7: -10000000, -128
<<8: 00000000, 0
<<9: 00000000, 0
-3 is, in two's complement, 11111101 and what you see when the program prints -0000011 is a - and the binary representation of the absolute value of the number. In two's complement, the highest bit is 0 for positive (including zero), and 1 for negative numbers. If you shift this number (11111101) left, the lower 7 bits move one to the left and a 0 comes in from the right, replacing the lowest bit. Shifting as you do in your example will result in:
11111101 -3
11111010 -6
11110100 -12
11101000 -24
11010000 -48
10100000 -96
01000000 64
10000000 -128
00000000 0
00000000 0
...
You just have to consider all the bit patterns as two's complement, once you know how that works, everything will make sense.

Tour of Go exercise #17: double less operator

In the Go Tour exercise #17, I don't understand this expression 1 << uint(i)
package main
import "fmt"
func main() {
pow := make([]int, 10)
for i := range pow {
pow[i] = 1 << uint(i)
}
for _, value := range pow {
fmt.Printf("%d\n", value)
}
}
What is the purpose of this operator ? <<
The program outputs:
1
2
4
8
16
32
64
128
256
512
Program exited.
Its a binary shift operator. Specifically, its a left shift (since they point to the left).
What it does, is move all bits in the binary representation of a number ... left.
For example. The binary representation of 1 is (with a safe assumption of 8 bits per byte): 00000001. Applying a left shift produces:
00000001
<<
00000010
Which is the binary representation of 2. Applying it again produces:
00000010
<<
00000100
..which is the binary representation of 4.. and so on.
Conversely, a right shift >> does the opposite, so applying >> to the value 4, produces:
00000100
>>
00000010
..2.
You can change the tour to count backwards by using the right shift operator:
pow[i] = 512 >> uint(i)

bitwise AND doesn't work on MSB

I'm implementing a bit vector by packing bits into an array of uints. The getBit(index) function does a (array[cell] & (1 << bit)) >> bit to get whether a bit has been set or not. This works perfectly well for all bits except the MSB. An example of where it doesn't work is as follows.
array[cell] = 11111001 11100000 00000000 00000000
(1 << bit) = 10000000 00000000 00000000 00000000
& operation = 01111001 11100000 00000000 00000000
I can't figure out why the Bitwise AND operation seems to be operating like an XOR. Either that or the MSB got unset. Can anyone explain whats happening?
Edit: Actual code
var cell:uint = int(index / 32);
var bit:uint = 32 - (index % 32) - 1;
return (array[cell] & (1 << bit)) >> bit;
In the instance that doesn't work, index = 0
If all values are such that things are well-defined,
(array[cell] & (1 << bit)) >> bit
is equivalent to the simpler
(array[cell] >> bit) & 1
for unsigned integers.
I'm not familiar with Action Script, but it could be that 1 << 31 behaves oddly because 1 is a signed integer.
Aside remark,
var bit:uint = 32 - (index % 32) - 1;
looks odd, usually one would use index % 32 as the bit number.
Use unsigned shift.
(uint(array[cell]) & (uint(1) << bit)) >>> bit

easy algorithm for using flags

Exists flags defs:
flag1=1
flag2=2
flag3=4
flag4=8
...
flagN=2^(N-1)
flag=flag1+flag2+...+flagN
if flagI not set, it eq 0
i have flag. which method can easily check, is for example flag2 defined?
Answer to your question
What's the range of flag? If it's under 2^64-1, almost every method is okay.
As #taskinoor posted, you should notice that:
flag1 = 000 ... ... 0001
flag2 = 000 ... ... 0010
flag3 = 000 ... ... 0100
In other words,
flag[n] = 1 << (n-1)
So, if you want to check all bits, a for loop and bitwise operation are fast enough to solve you problem. Like This (suppose you could understand C/C++ and flag is less than 2^32, which could be hold by an unsigned int in C/C++):
void check(unsigned int flag)
{
for (int i = 0; i < 32; ++i)
if ((flag & (1 << i)) != 0)
printf("flag%d defined!\n", i+1);
}
It's O(k), which k is the length of the type of flag in binary. For unsigned int, it's O(32) = O(1), almost in constant time.
If you just want to count how many flags defined:
I don't know what's your purpose. If you just want to count how many flags defined and flag is less than 2^64, the following method is awesome(suppose unsigned int as well):
unsigned int count_bit(unsigned int x)
{
x = (x & 0x55555555) + ((x >> 1) & 0x55555555);
x = (x & 0x33333333) + ((x >> 2) & 0x33333333);
x = (x & 0x0F0F0F0F) + ((x >> 4) & 0x0F0F0F0F);
x = (x & 0x00FF00FF) + ((x >> 8) & 0x00FF00FF);
x = (x & 0x0000FFFF) + ((x >> 16)& 0x0000FFFF);
return x;
}
If you call count_bit(1234567890), it'll return 12.
Let me explain this algorithm.
This algorithm is based on Divide and Conquer Algorithm. Suppose there is a 8bit integer 213(11010101 in binary), the algorithm works like this(each time merge two neighbor blocks):
+-------------------------------+
| 1 | 1 | 0 | 1 | 0 | 1 | 0 | 1 | <- x
| 1 0 | 0 1 | 0 1 | 0 1 | <- first time merge
| 0 0 1 1 | 0 0 1 0 | <- second time merge
| 0 0 0 0 0 1 0 1 | <- third time ( answer = 00000101 = 5)
+-------------------------------+
Note that in each flag only one bit is set to 1, others are 0.
flag1 = 000 ... ... 0001
flag2 = 000 ... ... 0010
flag3 = 000 ... ... 0100
// and like this
So if you do bitwise AND flag & flag2 then the result will be non-zero only if flag2 is defined.
r = flag & flag2;
if r != 0 then flag2 is defined
You can do this with all flags.
Boolean isSet (flags, flagN){
Return (flags & flagN) != 0;
}
Flags being the flag vector, flagN the flag you want to check
It is worth grokking the concept of bitmasks and flags more deeply. You can then use your imagination to represent state efficiently . (Just an example explained below)
First -Define the bitmask : 0x0000001c
What are the binary strings for which when you do an 'and' operation on the mask, you get a non-zero value?
Those are your valid flag values.
Valid flag values for this bitmask: 0x0000001c,0x00000014,0x00000018,0x00000004,0x00000008,etc ..
So, in your application if you can do the following:
flagvariable |= flagvalue1 ->Enable a particular flag.
if( flagvariable & maskvalue) :Check if a mask is enabled :
Then the different cases you would need to check :
if(flagvariable &maskvalue ==flagvalue1) { do something}
else
if(flagvariable &maskvalue ==flagvalue2) {do something else}
flagvariable &= `flagvalue1 : Clear the flag
To be more clear about flags and bitmasks, just step into gdb and do p /t and evaluate the the operations described above.

Resources