Returning bool from long integer class

P

Pierre Espenan

A have a long integer class. The built integer type within a conditional
statement returns bool false for int i=0 and bool true for any other non
zero value. I want my long integer class to have similar behavior. My
class looks like this:

#ifndef long_int_H
#define long_int_H
#include <string>
using namespace std;
typedef valarray<complex<double> > VCD;
typedef valarray<complex<float> > VCF;
typedef valarray<float> VAF;
typedef complex<double> COMPLEX;
const unsigned MAX_SIZE=1048576; //2^20
enum base{BIN=2, OCT=8, DEC=10, HEX=16};
base RAD=DEC;

class long_int{
friend ostream& operator<<(ostream& , const long_int& );
friend istream& operator>>(istream& , long_int& );
private:
base _radix;
string _str ;
int _len ;
long_int x_digit(const int&)const;
void x_radix();
void carry(VAF&)const;
string put_str()const;
static char itoc(const int& );
static int ctoi(const char&);
public:
long_int(base radix=RAD):_radix(radix),_str("0"),_len(1){}
explicit long_int(const string& s, base radix=RAD);
explicit long_int(const signed long& n, base radix=RAD);
long_int& operator=(const long_int& v);
long_int& operator=(const string& s);
long_int& operator=(const signed long& n);
long_int& operator+=(const long_int&);
long_int& operator++();
long_int operator++(int);
long_int& operator-=(const long_int&);
long_int& operator--();
long_int operator--(int);
long_int& operator*=(const long_int&);
long_int& operator/=(const long_int&);
long_int& operator%=(const long_int&);
long_int operator!()const;
long_int operator-()const;
long_int operator+()const;
long_int sqrt()const;
long_int abs()const;
void radix_convert(base radix=RAD);
int size()const;
bool operator<(const long_int&)const;
bool operator>(const long_int&)const;
bool operator==(const long_int&)const;
bool operator!=(const long_int&)const;
bool operator<=(const long_int&)const;
bool operator>=(const long_int&)const;
bool is_odd()const;
};
#endif


In my attempts to implement the bool functionality if I add "operator
bool()const{ if(*this==0) return false; else return true; }" below the bool
operators the compiler gives multiple warnings with the "<", "<=" and "%"
bool operators specifically "unsafe use of type 'bool' in operation". ( If
I remove the explicit qualifier from the second constructor I get multiple
errors --- "two overloads have similar conversions".) The warnings are
occuring in conditional statements within the definition of the arithmatic
operators. Are these warnings significant? Is this the correct way to
implement bool functionality?
 
P

Peter Koch Larsen

Pierre Espenan said:
A have a long integer class. The built integer type within a conditional
statement returns bool false for int i=0 and bool true for any other non
zero value. I want my long integer class to have similar behavior. My
class looks like this:

#ifndef long_int_H
#define long_int_H
#include <string>
using namespace std;
typedef valarray<complex<double> > VCD;
typedef valarray<complex<float> > VCF;
typedef valarray<float> VAF;
typedef complex<double> COMPLEX;
const unsigned MAX_SIZE=1048576; //2^20
enum base{BIN=2, OCT=8, DEC=10, HEX=16};
base RAD=DEC;

class long_int{
friend ostream& operator<<(ostream& , const long_int& );
friend istream& operator>>(istream& , long_int& );
private:
base _radix;
string _str ;
int _len ;
long_int x_digit(const int&)const;
void x_radix();
void carry(VAF&)const;
string put_str()const;
static char itoc(const int& );
static int ctoi(const char&);
public:
long_int(base radix=RAD):_radix(radix),_str("0"),_len(1){}
explicit long_int(const string& s, base radix=RAD);
explicit long_int(const signed long& n, base radix=RAD);
long_int& operator=(const long_int& v);
long_int& operator=(const string& s);
long_int& operator=(const signed long& n);
long_int& operator+=(const long_int&);
long_int& operator++();
long_int operator++(int);
long_int& operator-=(const long_int&);
long_int& operator--();
long_int operator--(int);
long_int& operator*=(const long_int&);
long_int& operator/=(const long_int&);
long_int& operator%=(const long_int&);
long_int operator!()const;
long_int operator-()const;
long_int operator+()const;
long_int sqrt()const;
long_int abs()const;
void radix_convert(base radix=RAD);
int size()const;
bool operator<(const long_int&)const;
bool operator>(const long_int&)const;
bool operator==(const long_int&)const;
bool operator!=(const long_int&)const;
bool operator<=(const long_int&)const;
bool operator>=(const long_int&)const;
bool is_odd()const;
};
#endif


In my attempts to implement the bool functionality if I add "operator
bool()const{ if(*this==0) return false; else return true; }" below the bool
operators the compiler gives multiple warnings with the "<", "<=" and "%"
bool operators specifically "unsafe use of type 'bool' in operation". ( If
I remove the explicit qualifier from the second constructor I get multiple
errors --- "two overloads have similar conversions".) The warnings are
occuring in conditional statements within the definition of the arithmatic
operators. Are these warnings significant? Is this the correct way to
implement bool functionality?

First, why don't you write your operator as

operator bool()const{ return *this!=0; }

this is more concise.

Second, your class does not permit you to compare your long_int with
ordinary integers. To do so, your class needs a constructor long_int(int i)
which is not explicit.

Third, your comparison functions should really be friends - as in
friend bool operator<(const long_int& lhs,const long_int& rhs);
this will enable you to write code such as:

int i;
long_int j;
....
if (i > j) ....

Fourth, there are problems with bool that suggest you better dont provide
such an operator. Instead use a conversion to void* const:

operator void* const(){ return *this!=0 ? this:0; }

This enables you to write

long_int j(0);
....
if (j) ...

Last, I do not see why you choose to expose your representation of radix to
the enduser. I would have opted for a radix-free long_int representation,
choosing a radix only when when outputting or inputting the numbers.

Kind regards
Peter
 
J

Jeff Schwab

Peter said:
( If



First, why don't you write your operator as

operator bool()const{ return *this!=0; }

this is more concise.

Right on.
Second, your class does not permit you to compare your long_int with
ordinary integers. To do so, your class needs a constructor long_int(int i)
which is not explicit.

Third, your comparison functions should really be friends - as in

Or, since I personally don't like friend functions, just make sure your
class provides enough public accessors for the comparisons to be
performed by functions outside the class.
friend bool operator<(const long_int& lhs,const long_int& rhs);
this will enable you to write code such as:

int i;
long_int j;
...
if (i > j) ....

Fourth, there are problems with bool that suggest you better dont provide
such an operator. Instead use a conversion to void* const:

operator void* const(){ return *this!=0 ? this:0; }

This enables you to write

long_int j(0);
...
if (j) ...

That's a fantastic idea I will be stealing for my own code. :)
 
P

Pierre Espenan

Peter Koch Larsen said:
First, why don't you write your operator as

operator bool()const{ return *this!=0; }
Thanks, I did but I had to do it like this:
operator bool()const{ return *this!=long_int(0); }
even after I took the explicit qualifier off the integer ctor
this is more concise.

Second, your class does not permit you to compare your long_int with
ordinary integers. To do so, your class needs a constructor long_int(int i)
which is not explicit. I took off the explicit

Third, your comparison functions should really be friends - as in
friend bool operator<(const long_int& lhs,const long_int& rhs);
this will enable you to write code such as:

int i;
long_int j;
...
if (i > j) ....
I didn't do this yet but I'll look into it.
Fourth, there are problems with bool that suggest you better dont provide
such an operator. Instead use a conversion to void* const:

operator void* const(){ return *this!=0 ? this:0; }
I had to do it the same way:
operator void* const(){ return *this!=long_int(0) ? this:0; }
to get it to work.
This enables you to write

long_int j(0);
...
if (j) ...

Last, I do not see why you choose to expose your representation of radix to
the enduser. I would have opted for a radix-free long_int representation,
choosing a radix only when when outputting or inputting the numbers.

I want the user to be able to change the radix.
The default radix is decimal. The overloaded cin operator takes the radix
of the long_int into account when inputting.
The radix can be converted between all four bases, for example:
100!=93326215443944152681699238856266700490715968264381621468592963895217599
993229915
6089414639761565182862536979208272237582511852109168640000000000000000000000
00 (DEC) =
1B30964EC395DC24069528D54BBDA40D16E966EF9A70EB21B5B2943A321CDF10391745570CCA
9420
C6ECB3B72ED2EE8B02EA2735C61A000000000000000000000000 (HEX)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,764
Messages
2,569,567
Members
45,041
Latest member
RomeoFarnh

Latest Threads

Top