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?
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)
|
:
Bearbeitet durch User
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
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)))
|
:
Bearbeitet durch User
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)))
|
Johann L. schrieb: > __builtin_clz nimmt nen int: Eher unsigned. Und es ist nicht nur der Cast Unsinn, sondern auch die 32 falsch. Korrekt wäre wohl:
1 | #include <limits.h> |
2 | #define BITSIZE(n) (CHAR_BIT * sizeof(unsigned) - __builtin_clz((n)))
|
:
Bearbeitet durch User
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!
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)
|
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.