-1

I am still kind of new to C++ and am trying to figure out what I am not able to pass a value correctly to a bitset, at least I suspect that is what the problem is. I wrote a small function to assist in flipping the bits of a hex value to reverse the endian. So example would be input 0x01 and it would return 0x80.

This is the code I wrote.

int flipBits(char msd, char lsd) {

char ch[5];
sprintf_s(ch, "0x%d%d", msd, lsd);
char buffer[5];
strncpy_s(buffer, ch, 4);
cout << ch << endl;
cout << buffer << endl;
bitset<8> x(buffer);
bitset<8> y;

for (int i = 0; i < 8; i++) {
    y[i] = x[7 - i];
}

cout << y << endl;              // print the reversed bit order
int b = y.to_ulong();           // convert the binary to int

cout << b << endl;              // print the int
cout << hex << b << endl;       // print the hex


return b;
}

I tried adding the strncpy because I thought maybe the null terminator from sprintf was not working properly with the bitset. If in the line

bitset<8> x(buffer);

I replace buffer with a hex value, say for example 0x01, then it works and prints out 0x80 as I would expect, but if I try to pass in the value with the buffer it doesn't work.

Nate
  • 37
  • 1
  • 4

1 Answers1

1

We can write a stl-like container wrapper such that we can write:

int main() {
    std::bitset<8> x(0x01);

    auto container = make_bit_range(x);
    std::reverse(container.begin(), container.end());

    std::cout << x << std::endl;
}

and expect the output:

10000000

full code:

#include <iostream>
#include <bitset>
#include <algorithm>

template<std::size_t N>
struct bit_reference  {
    bit_reference(std::bitset<N>& data, int i) : data_(data), i_(i) {}

    operator bool() const { return data_[i_]; }
    bit_reference& operator=(bool x) {
        data_[i_] = x;
        return *this;
    }

    std::bitset<N>& data_;
    int i_;
};

template<std::size_t N>
void swap(bit_reference<N> l, bit_reference<N> r) {
    auto lv = bool(l);
    auto rv = bool(r);
    std::swap(lv, rv);
    l = lv;
    r = rv;
}


template<std::size_t N>
struct bit_range {
    using bitset_type = std::bitset<N>;

    bit_range(bitset_type &data) : data_(data) {}

    struct iterator {
        using iterator_category = std::bidirectional_iterator_tag;
        using value_type = bit_reference<N>;
        using difference_type = int;
        using pointer = value_type *;
        using reference = value_type &;

        iterator(bitset_type &data, int i) : data_(data), i_(i) {}

        bool operator==(iterator const &r) const { return i_ == r.i_; }

        bool operator!=(iterator const &r) const { return i_ != r.i_; }

        iterator &operator--() {
            return update(i_ - 1);
        }

        iterator &operator++() {
            return update(i_ + 1);
        }

        value_type operator*() const {
            return bit_reference<N>(data_, i_);
        }

    private:
        auto update(int pos) -> iterator & {
            i_ = pos;
            return *this;
        }

    private:
        bitset_type &data_;
        int i_;
    };

    auto begin() const { return iterator(data_, 0); }

    auto end() const { return iterator(data_, int(data_.size())); }

private:
    bitset_type &data_;
};

template<std::size_t N>
auto make_bit_range(std::bitset<N> &data) {
    return bit_range<N>(data);
}


int main() {
    std::bitset<8> x(0x01);

    auto container = make_bit_range(x);
    std::reverse(container.begin(), container.end());

    std::cout << x << std::endl;
}

also plenty of fun algorithms here: Best Algorithm for Bit Reversal ( from MSB->LSB to LSB->MSB) in C

Richard Hodges
  • 68,278
  • 7
  • 90
  • 142