-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathNumberRepr.hpp
121 lines (86 loc) · 3 KB
/
NumberRepr.hpp
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
//
// Created by Lennart Oymanns on 03.05.17.
//
#ifndef NumberRepr_hpp
#define NumberRepr_hpp
#include <cmath>
#include <cstdlib>
#include <iomanip>
#include <sstream>
#include <string>
#include <boost/multiprecision/cpp_int.hpp>
namespace Equation {
using Integer_t = boost::multiprecision::cpp_int;
using Rational_t = boost::multiprecision::cpp_rational;
/** NumberRepr represents an actual number.
A number is either a fraction with denominator and numerator (with arbitrary
precision) or it is a floating point number.
*/
class NumberRepr {
public:
explicit NumberRepr();
explicit NumberRepr(const std::string &s);
explicit NumberRepr(long num, long denom = 1l) { SetFromInt(num, denom); }
explicit NumberRepr(const Rational_t &rat) {
isFraction = true;
isValid = true;
rational = rat;
}
explicit NumberRepr(const Integer_t &i) {
isFraction = true;
isValid = true;
rational = i;
}
explicit NumberRepr(double l) { SetFromDouble(l); }
NumberRepr &operator*=(const NumberRepr &rhs);
NumberRepr &operator/=(const NumberRepr &rhs);
NumberRepr &operator+=(const NumberRepr &rhs);
NumberRepr &operator-=(const NumberRepr &rhs);
void SetFromInt(long num, long denom = 1l);
void SetFromDouble(double l);
bool IsValid() const { return isValid; }
/** IsFraction returns true if this number is a fraction. */
bool IsFraction() const { return isFraction; }
double Double() const;
std::string String() const;
/** Numerator returns the numerator of the fraction.
Note, the result is only useful if IsFraction() is true. */
Integer_t Numerator() const {
return boost::multiprecision::numerator(rational);
}
/** Denominator returns the denominator of the fraction.
Note, the result is only useful if IsFraction() is true. */
Integer_t Denominator() const {
return boost::multiprecision::denominator(rational);
}
bool operator==(const NumberRepr &n) const;
bool operator!=(const NumberRepr &n) const { return !(*this == n); }
bool operator<(const NumberRepr &n);
bool operator>(const NumberRepr &n);
static NumberRepr Pow(const NumberRepr &base, const NumberRepr &exp);
void ToLatex(std::ostream &s) const;
private:
double value_double; ///< if isFraction==false, the value of this number
bool isFraction = false; ///< determines if this number is a fration or not
bool isValid = true; ///< determines if the number is valid
Rational_t rational; ///< if isFraction==true, the value of this number
};
inline NumberRepr operator+(NumberRepr lhs, const NumberRepr &rhs) {
lhs += rhs;
return lhs;
}
inline NumberRepr operator*(NumberRepr lhs, const NumberRepr &rhs) {
lhs *= rhs;
return lhs;
}
inline NumberRepr operator-(NumberRepr lhs, const NumberRepr &rhs) {
lhs -= rhs;
return lhs;
}
inline NumberRepr operator/(NumberRepr lhs, const NumberRepr &rhs) {
lhs /= rhs;
return lhs;
}
} // namespace Equation
std::ostream &operator<<(std::ostream &os, const Equation::NumberRepr &obj);
#endif /* NumberRepr_hpp */