Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » C / C++ (ANSI-Standard) » Bitzählen beliebiger Länge in logarithmischer Zeit

Forum | Hilfe | Team | Links | Impressum | > Suche < | Mitglieder | Registrieren | Einloggen
  Quicklinks: MSDN-Online || STL || clib Reference Grundlagen || Literatur || E-Books || Zubehör || > F.A.Q. < || Downloads   

Autor Thread - Seiten: > 1 <
000
09.01.2009, 23:56 Uhr
0xdeadbeef
Gott
(Operator)


Moin,

Ich bin eben mal wieder auf http://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetNaive gestoßen, eine sehr praktische Seite mit einem Haufen ausgesprochen nützlicher Performance-Hacks. Und als ich das so las, dachte ich mir: "Das muss doch auch generisch gehen. Wofür haben wir denn templates?"

Das vorläufige Ergebnis ist:

C++:
#include <iostream>

namespace impl {
  template<typename t> struct bitwidth {
    static int const val = sizeof(t) * 8;
  };

  template<typename t, int clumpsize, int it = bitwidth<t>::val / 4 / clumpsize> struct magic_builder_b {
    static t const clump = magic_builder_b<t, clumpsize, it / 2>::val;
    static t const val = clump | (clump << it * 2 * clumpsize);
  };

  template<typename t, int clumpsize>
  struct magic_builder_b<t, clumpsize, 0> {
    static t const val = (t(1) << clumpsize) - 1;
  };

  template<typename t, int ix> struct magic_numbers {
    static t const S = 1 << ix;
    static t const B = magic_builder_b<t, S>::val;
  };

  template<typename t, int it, bool finished> struct bitcounter {
    typedef magic_numbers<t, it> mnum;

    static inline int count(t x) {
      return bitcounter<t, it + 1,
    bitwidth<t>::val == mnum::S * 2>::count((x >> mnum::S) + x & mnum::B);
    }
  };

  template<typename t, bool finished> struct bitcounter<t, 0, finished> {
    typedef magic_numbers<t, 0> mnum;

    static inline int count(t x) {
      return bitcounter<t, 1,
    bitwidth<t>::val == mnum::S * 2>::count(x - (x >> 1 & mnum::B));
    }
  };

  template<typename t, bool finished> struct bitcounter<t, 1, finished> {
    typedef magic_numbers<t, 1> mnum;

    static inline int count(t x) {
      return bitcounter<t, 2,
    bitwidth<t>::val == mnum::S * 2>::count(((x >> mnum::S) & mnum::B)
                          + (x & mnum::B));
    }
  };

  template<typename t, int it> struct bitcounter<t, it, true> {
    static inline int count(t x) { return x; }
  };
}

template<typename t> int bitcount(t x) {
  return impl::bitcounter<t, 0, false>::count(x);
}

template<typename t> void print_binary(t x) {
  for(int i = 0; i < impl::bitwidth<t>::val; ++i) {
    std::cout << (x >> i & 1) ? '1' : '0';
  }
  std::cout << std::endl;
}

int main() {
  print_binary(impl::magic_builder_b<unsigned long long, 8>::val);
  print_binary(impl::magic_numbers<int, 4>::B);

  std::cout << bitcount(impl::magic_numbers<int, 4>::B) << std::endl;
  std::cout << bitcount(127ULL) << std::endl;
  std::cout << bitcount(-1L) << std::endl;
  std::cout << bitcount(short(-1)) << std::endl;
  std::cout << bitcount('A') << std::endl;

  print_binary(0xdeadbeef);
  std::cout << bitcount(0xdeadbeef) << std::endl;

  print_binary(-1234);
  std::cout << bitcount(-1234) << std::endl;
}



Meinungen?
--
Einfachheit ist Voraussetzung für Zuverlässigkeit.
-- Edsger Wybe Dijkstra

Dieser Post wurde am 10.01.2009 um 00:30 Uhr von 0xdeadbeef editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
Seiten: > 1 <     [ C / C++ (ANSI-Standard) ]  


ThWBoard 2.73 FloSoft-Edition
© by Paul Baecher & Felix Gonschorek (www.thwboard.de)

Anpassungen des Forums
© by Flo-Soft (www.flo-soft.de)

Sie sind Besucher: