Wildmeshing Toolkit
Loading...
Searching...
No Matches
Rational.hpp
1#pragma once
2
3#include <gmp.h>
4#include <iostream>
5#include <string>
6
7namespace wmtk {
8
10{
11public:
12 mpq_t value;
13 void canonicalize() { mpq_canonicalize(value); }
14 int get_sign() { return mpq_sgn(value); }
15 template <typename T>
16 void init(const T& v)
17 {
18 mpq_set(value, v);
19 }
20
21 void init_from_bin(const std::string& bin) { mpq_set_str(value, bin.c_str(), 2); }
22
23 Rational()
24 {
25 mpq_init(value);
26 mpq_set_d(value, 0);
27 }
28
29 Rational(double d)
30 {
31 mpq_init(value);
32 mpq_set_d(value, d);
33 // canonicalize();
34 }
35
36 Rational(const mpq_t& v_)
37 {
38 mpq_init(value);
39 mpq_set(value, v_);
40 // canonicalize();
41 }
42
43 Rational(const Rational& other)
44 {
45 mpq_init(value);
46 mpq_set(value, other.value);
47 }
48
49
50 ~Rational() { mpq_clear(value); }
51
52 friend Rational operator+(const Rational& x, const Rational& y)
53 {
54 Rational r_out;
55 mpq_add(r_out.value, x.value, y.value);
56 return r_out;
57 }
58
59 friend Rational operator-(const Rational& x, const Rational& y)
60 {
61 Rational r_out;
62 mpq_sub(r_out.value, x.value, y.value);
63 return r_out;
64 }
65
66
67 friend Rational operator-(const Rational& x)
68 {
69 Rational r_out;
70 mpq_neg(r_out.value, x.value);
71 return r_out;
72 }
73
74 friend Rational pow(const Rational& x, int p)
75 {
76 Rational r_out = x;
77 for (int i = 1; i < std::abs(p); i++) {
78 r_out = r_out * x;
79 }
80 if (p < 0) return 1 / r_out;
81 return r_out;
82 }
83
84 friend Rational operator*(const Rational& x, const Rational& y)
85 {
86 Rational r_out;
87 mpq_mul(r_out.value, x.value, y.value);
88 return r_out;
89 }
90
91 friend Rational operator/(const Rational& x, const Rational& y)
92 {
93 Rational r_out;
94 mpq_div(r_out.value, x.value, y.value);
95 return r_out;
96 }
97
98 Rational& operator=(const Rational& x)
99 {
100 if (this == &x) return *this;
101 mpq_set(value, x.value);
102 return *this;
103 }
104
105 Rational& operator=(const double x)
106 {
107 mpq_set_d(value, x);
108 // canonicalize();
109 return *this;
110 }
111
112 //> < ==
113 friend bool operator<(const Rational& r, const Rational& r1)
114 {
115 return mpq_cmp(r.value, r1.value) < 0;
116 }
117
118 friend bool operator>(const Rational& r, const Rational& r1)
119 {
120 return mpq_cmp(r.value, r1.value) > 0;
121 }
122
123 friend bool operator<=(const Rational& r, const Rational& r1)
124 {
125 return mpq_cmp(r.value, r1.value) <= 0;
126 }
127
128 friend bool operator>=(const Rational& r, const Rational& r1)
129 {
130 return mpq_cmp(r.value, r1.value) >= 0;
131 }
132
133 friend bool operator==(const Rational& r, const Rational& r1)
134 {
135 return mpq_equal(r.value, r1.value);
136 }
137
138 friend bool operator!=(const Rational& r, const Rational& r1)
139 {
140 return !mpq_equal(r.value, r1.value);
141 }
142
143 // to double
144 double to_double() const { return mpq_get_d(value); }
145 explicit operator double() const { return to_double(); }
146
147 // get str
148 std::string get_str()
149 {
150 char* s = mpq_get_str(NULL, 10, value);
151 std::string Str = s;
152 free(s);
153 return Str;
154 }
155
156 // get num str
157 std::string get_num_str() const
158 {
159 mpz_t num;
160 mpz_init(num);
161 mpq_get_num(num, value);
162 char* s = mpz_get_str(NULL, 10, num);
163 std::string Str = s;
164 free(s);
165 mpz_clear(num);
166 return Str;
167 }
168
169 // get den str
170 std::string get_den_str() const
171 {
172 mpz_t den;
173 mpz_init(den);
174 mpq_get_den(den, value);
175 char* s = mpz_get_str(NULL, 10, den);
176 std::string Str = s;
177 free(s);
178 mpz_clear(den);
179 return Str;
180 }
181
182 friend Rational abs(const Rational& r0)
183 {
184 Rational r;
185 mpq_abs(r.value, r0.value);
186 return r;
187 }
188
189 //<<
190 friend std::ostream& operator<<(std::ostream& os, const Rational& r)
191 {
192 os << mpq_get_d(r.value);
193 return os;
194 }
195};
196} // namespace wmtk
Definition Rational.hpp:10