How to determine how many bytes an integer needs?

前端 未结 22 1300
悲&欢浪女
悲&欢浪女 2020-12-13 02:13

I\'m looking for the most efficient way to calculate the minimum number of bytes needed to store an integer without losing precision.

e.g.

int: 10 = 1 byte
         


        
相关标签:
22条回答
  • 2020-12-13 02:49

    There are already a lot of answers here, but if you know the number ahead of time, in c++ you can use a template to make use of the preprocessor.

    template <unsigned long long N>
    struct RequiredBytes {
        enum : int { value = 1 + (N > 255 ? RequiredBits<(N >> 8)>::value : 0) };
    };
    
    template <>
    struct RequiredBytes<0> {
        enum : int { value = 1 };
    };
    
    const int REQUIRED_BYTES_18446744073709551615 = RequiredBytes<18446744073709551615>::value; // 8
    

    or for a bits version:

    template <unsigned long long N>
    struct RequiredBits {
        enum : int { value = 1 + RequiredBits<(N >> 1)>::value };
    };
    
    template <>
    struct RequiredBits<1> {
        enum : int { value = 1 };
    };
    
    template <>
    struct RequiredBits<0> {
        enum : int { value = 1 };
    };
    
    const int REQUIRED_BITS_42 = RequiredBits<42>::value; // 6
    
    0 讨论(0)
  • 2020-12-13 02:50

    This is based on SoapBox's idea of creating a solution that contains no jumps, branches etc... Unfortunately his solution was not quite correct. I have adopted the spirit and here's a 32bit version, the 64bit checks can be applied easily if desired.

    The function returns number of bytes required to store the given integer.

    unsigned short getBytesNeeded(unsigned int value)
    {
        unsigned short c = 0; // 0 => size 1
    
        c |= !!(value & 0xFF00); // 1 => size 2
        c |= (!!(value & 0xFF0000)) << 1; // 2 => size 3
        c |= (!!(value & 0xFF000000)) << 2; // 4 => size 4
    
        static const int size_table[] = { 1, 2, 3, 3, 4, 4, 4, 4 };
        return size_table[c];
    }
    
    0 讨论(0)
  • 2020-12-13 02:51

    Find the number of bits by taking the log2 of the number, then divide that by 8 to get the number of bytes.

    You can find logn of x by the formula:

    logn(x) = log(x) / log(n)

    Update:

    Since you need to do this really quickly, Bit Twiddling Hacks has several methods for quickly calculating log2(x). The look-up table approach seems like it would suit your needs.

    0 讨论(0)
  • 2020-12-13 02:52

    Floor((log2(N) / 8) + 1) bytes

    0 讨论(0)
  • 2020-12-13 02:53

    You could write a little template meta-programming code to figure it out at compile time if you need it for array sizes:

    template<unsigned long long N> struct NBytes
    { static const size_t value = NBytes<N/256>::value+1; };
    template<> struct NBytes<0> 
    { static const size_t value = 0; };
    
    int main()
    {
        std::cout << "short = " << NBytes<SHRT_MAX>::value << " bytes\n";
        std::cout << "int = " << NBytes<INT_MAX>::value << " bytes\n";
        std::cout << "long long = " << NBytes<ULLONG_MAX>::value << " bytes\n";
        std::cout << "10 = " << NBytes<10>::value << " bytes\n";
        std::cout << "257 = " << NBytes<257>::value << " bytes\n";
        return 0;
    }
    

    output:

    short = 2 bytes
    int = 4 bytes
    long long = 8 bytes
    10 = 1 bytes
    257 = 2 bytes
    

    Note: I know this isn't answering the original question, but it answers a related question that people will be searching for when they land on this page.

    0 讨论(0)
  • 2020-12-13 02:53

    there are lots of great recipes for stuff like this over at Sean Anderson's "Bit Twiddling Hacks" page.

    0 讨论(0)
提交回复
热议问题