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