27struct hash<mpq_class> {
28 size_t operator()(
const mpq_class &val)
const;
34std::strong_ordering operator<=>(
const mpq_class &lhs,
const mpq_t &rhs);
35std::strong_ordering operator<=>(
const mpq_t &lhs,
const mpq_class &rhs);
44mpz_class floor(
const mpq_class &val);
50mpz_class ceil(
const mpq_class &val);
81inline const mpq_t &ToMpq(
const mpq_class &cla) {
return *
reinterpret_cast<const mpq_t *
>(cla.get_mpq_t()); }
83inline mpq_t &ToMpq(mpq_class &cla) {
return *
reinterpret_cast<mpq_t *
>(cla.get_mpq_t()); }
93inline const mpq_class &ToMpqClass(
const mpq_t &mpq) {
return reinterpret_cast<const mpq_class &
>(mpq); }
103inline mpq_class &ToMpqClass(mpq_t &mpq) {
return reinterpret_cast<mpq_class &
>(mpq); }
111inline bool IsDigitOrSign(
char c) {
return std::isdigit(c) || c ==
'+' || c ==
'-'; }
143inline mpq_class StringToMpq(std::string_view str) {
145 const bool is_negative = str[0] ==
'-';
146 if (is_negative || str[0] ==
'+') str.remove_prefix(1);
147 if (str ==
"inf")
return {1e100};
148 if (str ==
"-inf")
return {-1e100};
151 const size_t symbol_pos = str.find_first_of(
"/.Ee");
152 if (symbol_pos == std::string::npos) {
153 const size_t start_pos = str.find_first_not_of(
'0', str[0] ==
'+' ? 1 : 0);
154 if (start_pos == std::string_view::npos)
return {0};
157 return is_negative ? -mpq_class{str.data() + start_pos} : mpq_class{str.data() + start_pos};
161 if (str[symbol_pos] ==
'/') {
162 mpq_class res{str.data()};
164 return is_negative ? -res : res;
167 const size_t e_pos = str[symbol_pos] ==
'e' || str[symbol_pos] ==
'E' ? symbol_pos : str.find_first_of(
"Ee");
168 mpz_class mult{is_negative ? -1 : 1};
169 bool is_exp_positive =
true;
172 if (e_pos != std::string::npos) {
173 const long exponent = std::stol(str.data() + e_pos + 1);
174 is_exp_positive = exponent >= 0;
176 mpz_pow_ui(mult.get_mpz_t(), mult.get_mpz_t(), std::abs(exponent));
177 if (is_negative) mult = -mult;
179 str = str.substr(0, e_pos);
181 if (str.empty())
return is_exp_positive ? mpq_class{mult} : is_negative ? mpq_class{-1, -mult} : mpq_class{1, mult};
184 const size_t &len = str.length();
187 if (str[symbol_pos] ==
'e' || str[symbol_pos] ==
'E') {
188 int plus_pos = str[0] ==
'+' ? 1 : 0;
192 char *
const str_number =
new char[len - plus_pos + 1];
193 memcpy(str_number, str.data() + plus_pos, len - plus_pos);
194 str_number[len - plus_pos] =
'\0';
195 mpq_class res{str_number, 10};
200 const size_t &dot_pos = symbol_pos;
203 size_t start_pos = str.find_first_not_of(
'0');
207 if (start_pos == dot_pos) {
208 start_pos = str.find_first_not_of(
'0', dot_pos + 1);
210 if (start_pos == std::string_view::npos) {
213 digits = len - start_pos;
216 digits = len - start_pos - 1;
219 const size_t n_decimals = len - dot_pos - 1;
224 char *
const str_number =
new char[digits + n_decimals + 3];
226 if (digits > n_decimals) {
227 memcpy(str_number, str.data() + start_pos, digits - n_decimals);
228 memcpy(str_number + dot_pos, str.data() + dot_pos + 1, n_decimals);
230 memcpy(str_number, str.data() + start_pos, n_decimals);
233 str_number[digits] =
'/';
234 str_number[digits + 1] =
'1';
235 memset(str_number + digits + 2,
'0', n_decimals);
236 str_number[digits + 2 + n_decimals] =
'\0';
238 mpq_class res{str_number, 10};
241 return is_exp_positive ? mpq_class{res * mult} : res / mult;
248#ifdef DLINEAR_INCLUDE_FMT
250#include "dlinear/util/logging.h"
252OSTREAM_FORMATTER(mpq_class)
Global namespace for the dlinear library.