1 
2 /*
3  *  Real - Implements a real number as either a floating point or as a ratio of arbitrary
4  *         sized integers
5  *  Format - Stores information about how to output a Real
6  *  Copyright (c) 2005 - 2006 by Mattias Hultgren <mattias_hultgren@tele2.se>
7  *
8  *
9  *   This program is free software; you can redistribute it and/or modify
10  *   it under the terms of the GNU General Public License as published by
11  *   the Free Software Foundation; version 2 of the License.
12  *
13  *   This program is distributed in the hope that it will be useful,
14  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
15  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  *   GNU General Public License for more details.
17  *
18  *   You should have received a copy of the GNU General Public
19  *   License along with this program; if not, write to the Free Software
20  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
21  */
22 
23 
24 #ifndef REAL_H_
25 #define REAL_H_
26 
27 #include "vartypes.h"
28 #include "integer.h"
29 #include "utf8_string.h"
30 
31 
32 #define REAL_H_VERSION "v4"
33 #define REAL_H_DATE    "2005-09 - 2006-10"
34 
35 
36 
37 
38 enum FormatType{ FormatType_Normal, FormatType_Mixed, FormatType_Science };
39 enum FormatFractionType{ FormatFractionType_Fractions, FormatFractionType_Integer_plus_fraction,
40                          FormatFractionType_Decimals };
41 class Format
42 {
43 private:
44 	floatx mixed_hilimit;
45 	floatx mixed_lowlimit;
46 
47 	FormatType type;
48 	FormatFractionType fraction_type;
49 	uint32 max_decimals;
50 
51 	void make_format_legal(void);
52 
53 public:
54 	bool show_trailingzeros;
55 
56 	Format();
57 	void set_type(FormatType newtype);
get_type(void)58 	inline FormatType get_type(void) const { return type; }
59 
60 	void set_fraction_type(FormatFractionType newtype);
get_fraction_type(void)61 	inline FormatFractionType get_fraction_type(void) const { return fraction_type; }
62 
63 	void set_max_decimals(uint32 n);
get_max_decimals(void)64 	inline uint32 get_max_decimals(void) const { return max_decimals; }
65 
66 
67 	// if lowlimit is higher than hilimit nothing will happen
68 	void set_mixed_limits(floatx lowlimit, floatx hilimit);
get_mixed_lowlimit(void)69 	inline floatx get_mixed_lowlimit(void) const { return mixed_lowlimit; }
get_mixed_hilimit(void)70 	inline floatx get_mixed_hilimit(void) const { return mixed_hilimit; }
71 };
72 
73 // if an exception is throwed the result in str may contain partly finished text
74 void floatx_to_string(floatx var, utf8_string &str, const Format &fmt) throw(error_obj);
75 
76 
77 
78 class Real
79 {
80 private:
81 	bool exact;
82 	union{
83 		floatx value;
84 		struct{
85 			Integer *top, *bottom;
86 		};
87 	};
88 
89 	void legalice(void);
90 
91 public:
Real()92 	Real() { exact = false; value = 0.0; }
Real(const floatx & new_value)93 	Real(const floatx &new_value) { exact = false; value = floatx(new_value); }
94 	Real(int32 new_value) throw(error_obj);
95 	Real(int64 new_value) throw(error_obj);
96 	Real(const Integer &new_value) throw(error_obj);
97 	Real(const Integer &new_top, const Integer &new_bottom) throw(error_obj);
98 	Real(const Real &val) throw(error_obj);
99 	~Real();
100 
101 
102 	void add( const Real &val ) throw(error_obj);
103 	void sub( const Real &val ) throw(error_obj);
104 	void mul( const Real &val ) throw(error_obj);
105 	void div( const Real &val ) throw(error_obj);
106 
isInteger(void)107 	inline bool isInteger(void) const { if( exact ) return ( *bottom == 1 ); else return false; }
isExact(void)108 	inline bool isExact(void) const { return exact; }
get_top(Integer * ptr)109 	inline void get_top( Integer *ptr ) const { if(exact) *ptr = *top; }
get_bottom(Integer * ptr)110 	inline void get_bottom( Integer *ptr ) const { if(exact) *ptr = *bottom; }
floatx(void)111 	inline operator floatx(void) const { if(exact) return floatx(*top)/floatx(*bottom); else return value; }
112 
113 	inline Real & operator++(void) throw(error_obj) { if(exact) top->add( *bottom ); else value++; return *this; }
114 	inline Real & operator++(int)  throw(error_obj) { if(exact) top->add( *bottom ); else value++; return *this; }
115 	inline Real & operator--(void) throw(error_obj) { if(exact) top->sub( *bottom ); else value--; return *this; }
116 	inline Real & operator--(int)  throw(error_obj) { if(exact) top->sub( *bottom ); else value--; return *this; }
117 
118 	Real operator+(const Real &val) const throw(error_obj);
119 	Real operator-(const Real &val) const throw(error_obj);
120 	Real operator*(const Real &val) const throw(error_obj);
121 	Real operator/(const Real &val) const throw(error_obj);
122 
123 	Real & operator=(const Real &val) throw(error_obj);
124 	inline Real & operator+=(const Real &val) throw(error_obj) { this->add( val ); return *this; }
125 	Real & operator-=(const Real &val) throw(error_obj) { this->sub( val ); return *this; }
throw(error_obj)126 	Real & operator*=(const Real &val) throw(error_obj) { this->mul( val ); return *this; }
throw(error_obj)127 	inline Real & operator*=(const int64 &val) throw(error_obj) { if(exact){ *top*=val; legalice(); }else value*=val; return *this;}
throw(error_obj)128 	inline Real & operator*=(const float &val) throw(error_obj) { if(exact){ value=floatx(*this)*val; exact=false; }else value*=val; return *this;}
throw(error_obj)129 	inline Real & operator*=(const double &val) throw(error_obj) { if(exact){ value=floatx(*this)*val; exact=false; }else value*=val; return *this;}
throw(error_obj)130 	inline Real & operator*=(const long double &val) throw(error_obj) { if(exact){ value=floatx(*this)*val; exact=false; }else value*=val; return *this;}
131 	Real & operator/=(const Real &val) throw(error_obj) { this->div( val ); return *this; }
132 
133 
134 	bool operator==(const Real &val) const;
135 	inline bool operator!=(const Real &val) const { return !(*this == val); };
136 
137 	bool operator<(const Real &val) const;
138 	bool operator>(const Real &val) const;
139 	inline bool operator<=(const Real &val) const { return !(*this > val); }
140 	inline bool operator>=(const Real &val) const { return !(*this < val); }
141 
142 	void append_to_string( utf8_string &str, const Format &fmt ) const throw(error_obj);
143 
144 	friend Real operator-(const Real &val) throw(error_obj);
145 	friend Real ipart(const Real &val) throw(error_obj);
146 	friend Real fpart(const Real &val) throw(error_obj);
147 	// converts a Real to a fraction
148 	friend Real frac(const Real &val, int32 highest_bottom_value) throw(error_obj);
149 	friend Real sign(const Real &val) throw(error_obj);
150 
151 	// val.isExact() must return true
152 	friend Real power(const Real &val, const Integer &nr) throw(error_obj);
153 };
154 
155 
156 
157 
158 
159 
160 #endif // REAL_H_
161