Wenn Sie sich Sorgen über einen Überlauf in einer C-ähnlichen Sprache mit (1 << param) - 1
(wenn param 32 oder 64 bei der maximalen Größe Typ die Maske wird 0 seit bitshift schiebt über die Grenzen des Typs), eine Lösung, die ich gerade gedacht:
const uint32_t mask = ( 1ul << ( maxBits - 1ul ) ) | ( ( 1ul << ( maxBits - 1ul ) ) - 1ul );
Oder ein anderes Beispiel
const uint64_t mask = ( 1ull << ( maxBits - 1ull ) ) | ( ( 1ull << ( maxBits - 1ull ) ) - 1ull );
Hier ist eine schablonenhafte Version, denken Sie daran, dass Sie diese mit einem unsignierten Typ R verwenden sollten:
#include <limits.h> /* CHAR_BIT */
// bits cannot be 0
template <typename R>
static constexpr R bitmask1( const R bits )
{
const R one = 1;
assert( bits >= one );
assert( bits <= sizeof( R ) * CHAR_BIT );
const R bitShift = one << ( bits - one );
return bitShift | ( bitShift - one );
}
Nehmen wir an, die maximale Anzahl von Bits ist 8 bei einem Byte, dann hätten wir mit der ersten überlaufenden Funktion 1 << 8 == 256
, was bei der Umwandlung in ein Byte zu 0 wird. Mit meiner Funktion haben wir 1 << 7 == 128
, die ein Byte enthalten kann, wird also 1<<7 | 1<<7 - 1
.
Ich habe die Funktion nicht kompiliert, daher kann sie Tippfehler enthalten.
Und zum Spaß gibt es hier Julien Royer ist ausgearbeitet:
// bits can be 0
template <typename R>
static constexpr R bitmask2( const R bits )
{
const R zero = 0;
const R mask = ~zero;
const R maxBits = sizeof( R ) * CHAR_BIT;
assert( bits <= maxBits );
return mask >> ( maxBits - bits );
}
0 Stimmen
Ihrer Beschreibung nach wäre dies wahrscheinlich das Einfachste, was Sie tun könnten bis Sie etwas eingebaut haben :p