log2() mit Preprocessor

Gast #3876893
Lesenswert?

Es gibt ja für fast alles irgendwelche klugen Makros.
Gibt es ein Makro was den Logarithmus zur Basis 2 einer zahl zurückgibt?
Genauer: die aufgerundete Anzahl an Bits die nötig ist, um eine Zahl zu 
speichern.

Beispiele:
BITSIZE(10) = 4
BITSIZE(255) = 8
BITSIZE(1100) = 11

Ist sowas möglich? Wie würde BITSIZE() aussehen?
#3876905
Lesenswert?

Beispiel für 8 Bits. Ist aber nur bei Konstanten sinnvoll. Je nach 
Prozessor und Compiler gehts auch anders.
1
#define BITSIZE(n) ((n) >= 128 ? 8 \
2
                  : (n) >=  64 ? 7 \
3
                  : (n) >=  32 ? 6 \
4
                  : (n) >=  16 ? 5 \
5
                  : (n) >=   8 ? 4 \
6
                  : (n) >=   4 ? 3 \
7
                  : (n) >=   2 ? 2 \
8
                  : 1)
Gast #3876927
Lesenswert?

Wenn es auch C++ sein darf (kein Makro):
1
template < unsigned N >
2
struct log2
3
{
4
    enum { result = 1 + log2< N / 2 >::result };
5
};
6

7
template <>
8
struct log2< 1 >
9
{
10
    enum { result = 0 };
11
};
12

13
#include <iostream>
14

15
int main()
16
{
17
    std::cout << "log2(1)" << log2<1>::result << std::endl;
18
    std::cout << "log2(4)" << log2<4>::result << std::endl;
19
    std::cout << "log2(1024)" << log2<1024>::result << std::endl;
20
}

mfg Torsten
Persönliche Seite #3877041
Lesenswert?

A. K. schrieb:
> Wenn n nicht immer konstant ist empfiehlt sich bei GCC etwas wie dies,
> weil dann je nach Prozessor auf entsprechenden Befehl abgebildet:
>
1
#define BITSIZE(n) (32 - __builtin_clz((uint32_t)(n)))

Der Cast ist überflüssig; __builtin_clz nimmt nen int:
1
#define BITSIZE(n) (8 * sizeof (int) - __builtin_clz ((n)))
oder eben
1
#define BITSIZE(n) (8 * sizeof (long) - __builtin_clzl ((long)(n)))
Gast #3877154
Lesenswert?

Ich war wohl etwas ungenau:
Es sollte C sein und ich verwende nur Konstante Werte, damit der 
Ausdruck zur Compilezeit konstant ist.
Damit dürfte hoffentlich A.K.s erste Antwort passen.

Danke dafür!
Gast #3893938
Lesenswert?

Es gibt noch eine nette Implementierung auf Stackoverflow, die auch 
32Bit verarbeiten kann:

"macro to compute number of bits needed to store a number n"
http://stackoverflow.com/questions/6834868/macro-to-compute-number-of-bits-needed-to-store-a-number-n

1
#define NBITS2(n) ((n&2)?1:0)
2
#define NBITS4(n) ((n&(0xC))?(2+NBITS2(n>>2)):(NBITS2(n)))
3
#define NBITS8(n) ((n&0xF0)?(4+NBITS4(n>>4)):(NBITS4(n)))
4
#define NBITS16(n) ((n&0xFF00)?(8+NBITS8(n>>8)):(NBITS8(n)))
5
#define NBITS32(n) ((n&0xFFFF0000)?(16+NBITS16(n>>16)):(NBITS16(n)))
6
#define NBITS(n) (n==0?0:NBITS32(n)+1)

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren