mybit.to_ulong()

Dear c/g++ expert:

why my g++(4.5.2)compiler can compile and run(well) of the example code of
------------
// bitset::to_ulong
#include <iostream>
#include <bitset>
using namespace std;

int main ()
{
bitset<4> mybits; // mybits: 0000

mybits.set(); // mybits: 1111

cout << mybits << " as an integer is: " << mybits.to_ulong() << endl;

return 0;
}
-----------------------------------------------------------------
but can not compile on
-----------
#include "big_int.hpp"

#include <iostream>
#include <vector>
#include <iterator>
#include <algorithm>

using namespace std;


void outputBigInt(BigInt<1024> x) {
vector<int> v;
if (x == 0) {
cout << 0;
return;
}
while (x > 0) {
v.push_back((x % 10).to_ulong());
x /= 10;
}
copy(v.rbegin(), v.rend(), ostream_iterator<int>(cout, ""));
cout << endl;
}

int main() {
BigInt<1024> n(1);
// compute 32 factorial
for (int i=1; i <= 32; ++i) {
n *= i;
}
outputBigInt(n);
}
----------------------------------------------------------------
root@eric-laptop:/home/eric/cppcookbook/ch11# g++ Example11-39.cpp
Example11-39.cpp: In function ‘void outputBigInt(BigInt<1024u>)’:
Example11-39.cpp:19:26: error: ‘class BigInt<1024u>::self’ has no member named ‘to_ulong’
--------------------------------------------------------------------------
this is bit_int.hpp
----------------------
#ifndef BIG_INT_HPP
#define BIG_INT_HPP

#include <bitset>

#include "bitset_arithmetic.hpp" // Recipe 11.20

template<unsigned int N>
class BigInt
{
typedef BigInt self;
public:
BigInt() : bits() { }
BigInt(const self& x) : bits(x.bits) { }
BigInt(unsigned long x) {
int n = 0;
while (x) {
bits[n++] = x & 0x1;
x >>= 1;
}
}
explicit BigInt(const std::bitset<N>& x) : bits(x) { }

// public functions
bool operator[](int n) const { return bits[n]; }
unsigned long toUlong() const { return bits.to_ulong(); }

// operator
self& operator<<=(unsigned int n) {
bits <<= n;
return *this;
}
self operator++(int) {
self i = *this;
operator++();
return i;
}
self operator--(int) {
self i = *this;
operator--();
return i;
}
self& operator++() {
bool carry = false;
bits[0] = fullAdder(bits[0], 1, carry);
for (int i = 1; i < N; i++) {
bits[i] = fullAdder(bits[i], 0, carry);
}
return *this;
}
self& operator--() {
bool borrow = false;
bits[0] = fullSubstractor(bits[0], 1, borrow);
for (int i = 1; i < N; i++) {
bits[i] = fullSubtractor(bits[i], 0, borrow);
}
return *this;
}
self& operator+=(const self& x) {
bitsetAdd(bits, x.bits);
return *this;
}
self& operator-=(const self& x) {
bitsetSubtract(bits, x.bits);
return *this;
}
self& operator*=(const self& x) {
bitsetMultiply(bits, x.bits);
return *this;
}
self& operator/=(const self& x) {
std::bitset<N> tmp;
bitsetDivide(bits, x.bits, bits, tmp);
return *this;
}
self& operator%=(const self& x) {
std::bitset<N> tmp;
bitsetDivide(bits, x.bits, tmp, bits);
return *this;
}
self operator~() const { return ~bits; }
self& operator&=(self x) { bits &= x.bits; return *this; }
self& operator|=(self x) { bits |= x.bits; return *this; }
self& operator^=(self x) { bits ^= x.bits; return *this; }

// friend functions
friend self operator<<(self x, unsigned int n) { return x <<= n; }
friend self operator>>(self x, unsigned int n) { return x >>= n; }
friend self operator+(self x, const self& y) { return x += y; }
friend self operator-(self x, const self& y) { return x -= y; }
friend self operator*(self x, const self& y) { return x *= y; }
friend self operator/(self x, const self& y) { return x /= y; }
friend self operator%(self x, const self& y) { return x %= y; }
friend self operator^(self x, const self& y) { return x ^= y; }
friend self operator&(self x, const self& y) { return x &= y; }
friend self operator|(self x, const self& y) { return x |= y; }

// comparison operators
friend bool operator==(const self& x, const self& y) {
return x.bits == y.bits;
}
friend bool operator!=(const self& x, const self& y) {
return x.bits != y.bits;
}
friend bool operator>(const self& x, const self& y) {
return bitsetGt(x.bits, y.bits);
}
friend bool operator<(const self& x, const self& y) {
return bitsetLt(x.bits, y.bits);
}
friend bool operator>=(const self& x, const self& y) {
return bitsetGtEq(x.bits, y.bits);
}
friend bool operator<=(const self& x, const self& y) {
return bitsetLtEq(x.bits, y.bits);
}
private:
std::bitset<N> bits;
};

#endif
--------------------------------------------------------
plz help, thanks a lot in advance, Eric
I can't read that like that, could you put some code tags around it?
bitset_arithmetic.hpp
----------------------------------
#include <stdexcept>
#include <bitset>

bool fullAdder(bool b1, bool b2, bool& carry) {
bool sum = (b1 ^ b2) ^ carry;
carry = (b1 && b2) || (b1 && carry) || (b2 && carry);
return sum;
}

bool fullSubstractor(bool b1, bool b2, bool& borrow) {
bool diff;
if (borrow) {
diff = !(b1 ^ b2);
borrow = !b1 || (b1 && b2);
}
else {
diff = b1 ^ b2;
borrow = !b1 && b2;
}
return diff;
}

template<unsigned int N>
bool bitsetLtEq(const std::bitset<N>& x, const std::bitset<N>& y)
{
for (int i=N-1; i >= 0; i--) {
if (x[i] && !y[i]) return false;
if (!x[i] && y[i]) return true;
}
return true;
}

template<unsigned int N>
bool bitsetLt(const std::bitset<N>& x, const std::bitset<N>& y)
{
for (int i=N-1; i >= 0; i--) {
if (x[i] && !y[i]) return false;
if (!x[i] && y[i]) return true;
}
return false;
}

template<unsigned int N>
bool bitsetGtEq(const std::bitset<N>& x, const std::bitset<N>& y)
{
for (int i=N-1; i >= 0; i--) {
if (x[i] && !y[i]) return true;
if (!x[i] && y[i]) return false;
}
return true;
}

template<unsigned int N>
bool bitsetGt(const std::bitset<N>& x, const std::bitset<N>& y)
{
for (int i=N-1; i >= 0; i--) {
if (x[i] && !y[i]) return true;
if (!x[i] && y[i]) return false;
}
return false;
}

template<unsigned int N>
void bitsetAdd(std::bitset<N>& x, const std::bitset<N>& y)
{
bool carry = false;
for (int i = 0; i < N; i++) {
x[i] = fullAdder(x[i], y[i], carry);
}
}

template<unsigned int N>
void bitsetSubtract(std::bitset<N>& x, const std::bitset<N>& y) {
bool borrow = false;
for (int i = 0; i < N; i++) {
if (borrow) {
if (x[i]) {
x[i] = y[i];
borrow = y[i];
}
else {
x[i] = !y[i];
borrow = true;
}
}
else {
if (x[i]) {
x[i] = !y[i];
borrow = false;
}
else {
x[i] = y[i];
borrow = y[i];
}
}
}
}

template<unsigned int N>
void bitsetMultiply(std::bitset<N>& x, const std::bitset<N>& y)
{
std::bitset<N> tmp = x;
x.reset();

// we want to minimize the number of time we shift and add
if (tmp.count() < y.count()) {
for (int i=0; i < N; i++)
if (tmp[i]) bitsetAdd(x, tmp << i);
}
}

template<unsigned int N>
void bitsetDivide(std::bitset<N> x, std::bitset<N> y,
std::bitset<N>& q, std::bitset<N>& r)
{
if (y.none()) {
throw std::domain_error("division by zero undefined");
}
q.reset();
r.reset();
if (x.none()) {
return;
}
r = x;
if (bitsetLt(x, y)) {
return;
}
// count significant digits in divisor and dividend
unsigned int sig_x;
for (int i=N-1; i>=0; i--) {
sig_x = 1;
if (x[i]) break;
}
unsigned int sig_y;
for (int i=N-1; i>=0; i--) {
sig_y = 1;
if (y[i]) break;
}

// align the divisor with the dividend
unsigned int n = (sig_x - sig_y);
y <<= n;

// make sure the loop executes the right number of times
n += 1;

// long division algorithm, shift, and subtract
while (n--)
{
// shift the quotient to the left
if (bitsetLtEq(y, r))
{
// add a new digit to quotient
q[n] = true;
bitsetSubtract(r, y);
}
// shift the divisor to the right
y >>= 1;
}
}

----------------------------------------
all these example code, you can download directly from
http://examples.oreilly.com/9780596007614/
-----
11-38
11-39
11-36
----------------------------------------------------------------
since my g++ compiler work at cplusplus.com 's example code, so It prove that maybe somewhere wrong on that book's example
code.
Hope all these are sufficient enough for experts to debug
sincerely, Eric
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161

#include <stdexcept>
#include <bitset>

bool fullAdder(bool b1, bool b2, bool& carry) {
bool sum = (b1 ^ b2) ^ carry;
carry = (b1 && b2) || (b1 && carry) || (b2 && carry);
return sum;
}

bool fullSubstractor(bool b1, bool b2, bool& borrow) {
bool diff;
if (borrow) {
diff = !(b1 ^ b2);
borrow = !b1 || (b1 && b2);
}
else {
diff = b1 ^ b2;
borrow = !b1 && b2;
}
return diff;
}

template<unsigned int N>
bool bitsetLtEq(const std::bitset<N>& x, const std::bitset<N>& y)
{
for (int i=N-1; i >= 0; i--) {
if (x[i] && !y[i]) return false;
if (!x[i] && y[i]) return true;
}
return true;
}

template<unsigned int N>
bool bitsetLt(const std::bitset<N>& x, const std::bitset<N>& y)
{
for (int i=N-1; i >= 0; i--) {
if (x[i] && !y[i]) return false;
if (!x[i] && y[i]) return true;
}
return false;
}

template<unsigned int N>
bool bitsetGtEq(const std::bitset<N>& x, const std::bitset<N>& y)
{
for (int i=N-1; i >= 0; i--) {
if (x[i] && !y[i]) return true;
if (!x[i] && y[i]) return false;
}
return true;
}

template<unsigned int N>
bool bitsetGt(const std::bitset<N>& x, const std::bitset<N>& y)
{
for (int i=N-1; i >= 0; i--) {
if (x[i] && !y[i]) return true;
if (!x[i] && y[i]) return false;
}
return false;
}

template<unsigned int N>
void bitsetAdd(std::bitset<N>& x, const std::bitset<N>& y)
{
bool carry = false;
for (int i = 0; i < N; i++) {
x[i] = fullAdder(x[i], y[i], carry);
}
}

template<unsigned int N>
void bitsetSubtract(std::bitset<N>& x, const std::bitset<N>& y) {
bool borrow = false;
for (int i = 0; i < N; i++) {
if (borrow) {
if (x[i]) {
x[i] = y[i];
borrow = y[i];
}
else {
x[i] = !y[i];
borrow = true;
}
}
else {
if (x[i]) {
x[i] = !y[i];
borrow = false;
}
else {
x[i] = y[i];
borrow = y[i];
}
}
}
}

template<unsigned int N>
void bitsetMultiply(std::bitset<N>& x, const std::bitset<N>& y)
{
std::bitset<N> tmp = x;
x.reset();

// we want to minimize the number of time we shift and add
if (tmp.count() < y.count()) {
for (int i=0; i < N; i++)
if (tmp[i]) bitsetAdd(x, tmp << i);
}
}

template<unsigned int N>
void bitsetDivide(std::bitset<N> x, std::bitset<N> y,
std::bitset<N>& q, std::bitset<N>& r)
{
if (y.none()) {
throw std::domain_error("division by zero undefined");
}
q.reset();
r.reset();
if (x.none()) {
return;
}
r = x;
if (bitsetLt(x, y)) {
return;
}
// count significant digits in divisor and dividend
unsigned int sig_x;
for (int i=N-1; i>=0; i--) {
sig_x = 1;
if (x[i]) break;
}
unsigned int sig_y;
for (int i=N-1; i>=0; i--) {
sig_y = 1;
if (y[i]) break;
}

// align the divisor with the dividend
unsigned int n = (sig_x - sig_y);
y <<= n;

// make sure the loop executes the right number of times
n += 1;

// long division algorithm, shift, and subtract
while (n--)
{
// shift the quotient to the left
if (bitsetLtEq(y, r))
{
// add a new digit to quotient
q[n] = true;
bitsetSubtract(r, y);
}
// shift the divisor to the right
y >>= 1;
}
}

Please use code tags
Topic archived. No new replies allowed.