Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get a number from unsigned long long mask?

Tags:

c++

I wonder how to reverse something like this. So having a mask where auto mask = 1ULL << 20; how to get 20 out from mask?

like image 838
myWallJSON Avatar asked Apr 22 '13 06:04

myWallJSON


People also ask

What is the difference between unsigned long and unsigned long long?

unsigned long is required to be at least 32 bits. unsigned long long is required to be at least 64 bits. (Actually the requirements are stated in terms of the ranges of values they can represent.) As you've seen, this is consistent with them both being the same size, as long as that size is at least 64 bits.

How many bytes is an unsigned long?

Unsigned long variables are extended size variables for number storage, and store 32 bits (4 bytes). Unlike standard longs unsigned longs won't store negative numbers, making their range from 0 to 4,294,967,295 (2^32 - 1).

How do you define unsigned long long?

An unsigned long long occupies 8 bytes of memory; it stores an integer from 0 to 2^64-1, which is approximately 1.8×10^19 (18 quintillion, or 18 billion billion). A synonym for the unsigned long long type is uint64 .


2 Answers

Loop-free

Many years ago when I was writing a bit-wise arithmetic for a chess engine, I found a fast implementation which is useful for your requirement, it's loop-free. This method will return the position of the first 1-bit from right-to-left (Least Significant Bit):

inline unsigned int lsb(unsigned long long value)
{
    if (!value)
        return -1;

    value &= -value;
    unsigned int lsb = (unsigned) value | (unsigned) (value >> 32);
    return (((((((((((unsigned) (value >> 32) != 0) << 1)
            + ((lsb & 0xffff0000) != 0)) << 1)
            + ((lsb & 0xff00ff00) != 0)) << 1)
            + ((lsb & 0xf0f0f0f0) != 0)) << 1)
            + ((lsb & 0xcccccccc) != 0)) << 1)
            + ((lsb & 0xaaaaaaaa) != 0);
}

int main()
{
    unsigned long long x = 1ULL<<20;
    cout << lsb(x) << endl;
}

Output

20

I think, I had found it here.

like image 150
masoud Avatar answered Sep 17 '22 15:09

masoud


Using log:

#include <iostream>
#include <cmath>
int main() {
    auto mask = 1ULL << 20; 
    std::cout << log2(mask) << std::endl;
    // edit out: std::cout << log(mask) / log(2) << std::endl;
    return 0;
}

or loop and shift:

#include <iostream>
int main() {
    auto mask = 1ULL << 20; 
    for (unsigned int c = 0; c < sizeof(mask) * 8 && mask; c++) {
        mask >>= 1;
        if (mask == 0)
            std::cout << c << std::endl;
    }   
    return 0;
}
like image 39
perreal Avatar answered Sep 18 '22 15:09

perreal