Читаем Thinking In C++. Volume 2: Practical Programming полностью

  cout << "as a string = " << cbits <

  cout << BS(cbits) << " [BS(cbits)]" << endl;

  cout << BS(cbits, 2)

    << " [BS(cbits, 2)]" << endl;

  cout << BS(cbits, 2, 11)

    << " [BS(cbits, 2, 11)]" << endl;

  cout << a << " [a]" << endl;

  cout << b << " [b]" << endl;

  // Bitwise AND:

  cout << (a & b) << " [a & b]" << endl;

  cout << (BS(a) &= b) << " [a &= b]" << endl;

  // Bitwise OR:

  cout << (a | b) << " [a | b]" << endl;

  cout << (BS(a) |= b) << " [a |= b]" << endl;

  // Exclusive OR:

  cout << (a ^ b) << " [a ^ b]" << endl;

  cout << (BS(a) ^= b) << " [a ^= b]" << endl;

  cout << a << " [a]" << endl; // For reference

  // Logical left shift (fill with zeros):

  cout << (BS(a) <<= sz/2)

    << " [a <<= (sz/2)]" << endl;

  cout << (a << sz/2) << endl;

  cout << a << " [a]" << endl; // For reference

  // Logical right shift (fill with zeros):

  cout << (BS(a) >>= sz/2)

    << " [a >>= (sz/2)]" << endl;

  cout << (a >> sz/2) << endl;

  cout << a << " [a]" << endl; // For reference

  cout << BS(a).set() << " [a.set()]" << endl;

  for(int i = 0; i < sz; i++)

    if(!a.test(i)) {

      cout << BS(a).set(i)

        << " [a.set(" << i <<")]" << endl;

      break; // Just do one example of this

    }

  cout << BS(a).reset() << " [a.reset()]"<< endl;

  for(int j = 0; j < sz; j++)

    if(a.test(j)) {

      cout << BS(a).reset(j)

        << " [a.reset(" << j <<")]" << endl;

      break; // Just do one example of this

    }

  cout << BS(a).flip() << " [a.flip()]" << endl;

  cout << ~a << " [~a]" << endl;

  cout << a << " [a]" << endl; // For reference

  cout << BS(a).flip(1) << " [a.flip(1)]"<< endl;

  BS c;

  cout << c << " [c]" << endl;

  cout << "c.count() = " << c.count() << endl;

  cout << "c.any() = "

    << (c.any() ? "true" : "false") << endl;

  cout << "c.none() = "

    << (c.none() ? "true" : "false") << endl;

  c[1].flip(); c[2].flip();

  cout << c << " [c]" << endl;

  cout << "c.count() = " << c.count() << endl;

  cout << "c.any() = "

    << (c.any() ? "true" : "false") << endl;

  cout << "c.none() = "

    << (c.none() ? "true" : "false") << endl;

  // Array indexing operations:

  c.reset();

  for(int k = 0; k < c.size(); k++)

    if(k % 2 == 0)

      c[k].flip();

  cout << c << " [c]" << endl;

  c.reset();

  // Assignment to bool:

  for(int ii = 0; ii < c.size(); ii++)

    c[ii] = (rand() % 100) < 25;

  cout << c << " [c]" << endl;

  // bool test:

  if(c[1])

    cout << "c[1] == true";

  else

    cout << "c[1] == false" << endl;

} ///:~

To generate interesting random bitsets, the randBitset( ) function is created. This function demonstrates operator<<= by shifting each 16 random bits to the left until the bitset (which is templatized in this function for size) is full. The generated number and each new 16 bits are combined using the operator|=.

The first thing demonstrated in main( ) is the unit size of a bitset. If it is less than 32 bits, sizeof produces 4 (4 bytes = 32 bits), which is the size of a single long on most implementations. If it’s between 32 and 64, it requires two longs, greater than 64 requires 3 longs, and so on. Thus, you make the best use of space if you use a bit quantity that fits in an integral number of longs. However, notice there’s no extra overhead for the object—it’s as if you were hand-coding to use a long.

Although there are no other numerical conversions from bitset besides to_ulong( ), there is a stream inserter that produces a string containing ones and zeros, and this can be as long as the actual bitset.

There’s still no primitive format for binary values, but the next best thing is supported by bitset: a string of ones and zeros with the least-significant bit (lsb) on the right. The three constructors demonstrated show taking the entire string, the string starting at character 2, and the string from character 2 through 11. You can write to an ostream from a bitset using operator<<, and it comes out as ones and zeros. You can also read from an istream using operator>> (not shown here).

You’ll notice that bitset only has three nonmember operators: and (&), or (|), and exclusive-or (^). Each of these creates a new bitset as its return value. All the member operators opt for the more efficient &=, |=, and so on form in which a temporary is not created. However, these forms actually change the bitset’s value (which is a in most of the tests in the above example). To prevent this, we created a temporary to be used as the lvalue by invoking the copy-constructor on a; this is why you see the form BS(a). The result of each test is printed out, and occasionally a is reprinted so you can easily look at it for reference.

The rest of the example should be self-explanatory when you run it; if not you can find the details in your compiler’s documentation or in the other documentation mentioned earlier in this chapter.

Перейти на страницу:

Похожие книги

3ds Max 2008
3ds Max 2008

Одни уверены, что нет лучшего способа обучения 3ds Мах, чем прочитать хорошую книгу. Другие склоняются к тому, что эффективнее учиться у преподавателя, который показывает, что и как нужно делать. Данное издание объединяет оба подхода. Его цель – сделать освоение 3ds Мах 2008 максимально быстрым и результативным. Часто после изучения книги у читателя возникают вопросы, почему не получился тот или иной пример. Видеокурс – это гарантия, что такие вопросы не возникнут: ведь автор не только рассказывает, но и показывает, как нужно работать в 3ds Мах.В отличие от большинства интерактивных курсов, где работа в 3ds Мах иллюстрируется на кубиках-шариках, данный видеокурс полностью практический. Все приемы работы с инструментами 3ds Мах 2008 показаны на конкретных примерах, благодаря чему после просмотра курса читатель сможет самостоятельно выполнять даже сложные проекты.

Владимир Антонович Верстак , Владимир Верстак

Программирование, программы, базы данных / Программное обеспечение / Книги по IT