SMTStabilizer API
Public API documentation for SMTStabilizer
Loading...
Searching...
No Matches
number.cpp
Go to the documentation of this file.
1/* -*- Source -*-
2 *
3 * The Numbers
4 *
5 * Author: Fuqi Jia <jiafq@ios.ac.cn>
6 *
7 * Copyright (C) 2025 Fuqi Jia
8 *
9 * Permission is hereby granted, free of charge, to any person obtaining a
10 * copy of this software and associated documentation files (the "Software"),
11 * to deal in the Software without restriction, including without limitation
12 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
13 * and/or sell copies of the Software, and to permit persons to whom the
14 * Software is furnished to do so, subject to the following conditions:
15 *
16 * The above copyright notice and this permission notice shall be included in
17 * all copies or substantial portions of the Software.
18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
24 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
25 * DEALINGS IN THE SOFTWARE.
26 */
27
28// Modified by Xiang Zhang, 2026
29// Additional changes licensed under the MIT License
30
31#include "number.h"
32
33#include <climits> // For LLONG_MAX and LLONG_MIN
34#include <cmath>
35#include <stdexcept>
36#include <string>
37
38namespace stabilizer::parser {
39
40// -------------HighPrecisionReal-------------
41// Constants
43 HighPrecisionReal result(precision);
44 mpfr_const_pi(result.value, MPFR_RNDN);
45 return result;
46}
47
49 HighPrecisionReal result(precision);
50 // use exp(1) to calculate e
51 mpfr_set_ui(result.value, 1, MPFR_RNDN);
52 mpfr_exp(result.value, result.value, MPFR_RNDN);
53 return result;
54}
55
57 HighPrecisionReal result(precision);
58 // φ = (1 + sqrt(5)) / 2
59 HighPrecisionReal five(5, precision);
60 HighPrecisionReal sqrt5 = five.sqrt();
61 HighPrecisionReal one(1, precision);
62 mpfr_add(result.value, one.value, sqrt5.value, MPFR_RNDN);
63 mpfr_div_ui(result.value, result.value, 2, MPFR_RNDN);
64 return result;
65}
66
68 HighPrecisionReal result(precision);
69 mpfr_const_log2(result.value, MPFR_RNDN);
70 return result;
71}
72
74 HighPrecisionReal result(precision);
75 HighPrecisionReal ten(10, precision);
76 mpfr_log(result.value, ten.value, MPFR_RNDN);
77 return result;
78}
79
81 HighPrecisionReal result(precision);
82 // log₂(e) = 1/ln(2)
83 mpfr_const_log2(result.value, MPFR_RNDN);
84 mpfr_ui_div(result.value, 1, result.value, MPFR_RNDN);
85 return result;
86}
87
89 HighPrecisionReal result(precision);
90 // log₁₀(e) = 1/ln(10)
91 HighPrecisionReal ten(10, precision);
92 mpfr_log(result.value, ten.value, MPFR_RNDN);
93 mpfr_ui_div(result.value, 1, result.value, MPFR_RNDN);
94 return result;
95}
96
98 HighPrecisionReal result(precision);
99 mpfr_const_euler(result.value, MPFR_RNDN);
100 return result;
101}
102
104 HighPrecisionReal result(precision);
105 mpfr_const_catalan(result.value, MPFR_RNDN);
106 return result;
107}
108
110 mpfr_t one, next, eps;
111 mpfr_init2(one, precision);
112 mpfr_init2(next, precision);
113 mpfr_init2(eps, precision);
114
115 mpfr_set_ui(one, 1, MPFR_RNDN); // one = 1
116 mpfr_set(next, one, MPFR_RNDN); // next = 1
117 mpfr_nextabove(next); // next = next representable number > 1
118 mpfr_sub(eps, next, one, MPFR_RNDN); // eps = next - 1
119 return HighPrecisionReal(eps);
120}
121
122// Constructor
124 mpfr_init2(value, precision);
125 mpfr_set_zero(value, 1); // Initialize to +0
126}
127
128HighPrecisionReal::HighPrecisionReal(int i, mpfr_prec_t precision) {
129 mpfr_init2(value, precision);
130 mpfr_set_si(value, i, MPFR_RNDN);
131}
132
133HighPrecisionReal::HighPrecisionReal(const Integer &i, mpfr_prec_t precision) {
134 mpfr_init2(value, precision);
135 mpfr_set_z(value, i.getMPZ().get_mpz_t(), MPFR_RNDN);
136}
137
138HighPrecisionReal::HighPrecisionReal(const double &d, mpfr_prec_t precision) {
139 mpfr_init2(value, precision);
140 mpfr_set_d(value, d, MPFR_RNDN);
141}
142
143HighPrecisionReal::HighPrecisionReal(const float &f, mpfr_prec_t precision) {
144 mpfr_init2(value, precision);
145 mpfr_set_flt(value, f, MPFR_RNDN);
146}
147
149 mpfr_prec_t precision) {
150 mpfr_init2(value, precision); // Initialize value
151
152 if (mpfr_set_str(value, s.c_str(), 10, MPFR_RNDN) != 0) {
153 mpfr_clear(value);
154 throw std::invalid_argument(
155 "Cannot convert string to high precision real number");
156 }
157}
158
159HighPrecisionReal::HighPrecisionReal(const char *s, mpfr_prec_t precision) {
160 mpfr_init2(value, precision); // Initialize value
161
162 if (mpfr_set_str(value, s, 10, MPFR_RNDN) != 0) {
163 mpfr_clear(value);
164 throw std::invalid_argument(
165 "Cannot convert string to high precision real number");
166 }
167}
168
169HighPrecisionReal::HighPrecisionReal(const mpfr_t &t, mpfr_prec_t precision) {
170 mpfr_init2(value, precision);
171 mpfr_set(value, t, MPFR_RNDN);
172}
173
175 mpfr_init2(value, mpfr_get_prec(other.value));
176 mpfr_set(value, other.value, MPFR_RNDN);
177}
178
179// Assignment operator
182 if (this != &other) {
183 // If precision is different, reinitialize
184 if (mpfr_get_prec(value) != mpfr_get_prec(other.value)) {
185 mpfr_clear(value);
186 mpfr_init2(value, mpfr_get_prec(other.value));
187 }
188 mpfr_set(value, other.value, MPFR_RNDN);
189 }
190 return *this;
191}
192
193// Destructor
195
196// Basic arithmetic operators
199 HighPrecisionReal result(
200 std::max(mpfr_get_prec(value), mpfr_get_prec(other.value)));
201 mpfr_add(result.value, value, other.value, MPFR_RNDN);
202 return result;
203}
204
207 HighPrecisionReal result(
208 std::max(mpfr_get_prec(value), mpfr_get_prec(other.value)));
209 mpfr_sub(result.value, value, other.value, MPFR_RNDN);
210 return result;
211}
212
214 HighPrecisionReal result(mpfr_get_prec(value));
215 mpfr_neg(result.value, value, MPFR_RNDN);
216 return result;
217}
218
221 HighPrecisionReal result(
222 std::max(mpfr_get_prec(value), mpfr_get_prec(other.value)));
223 mpfr_mul(result.value, value, other.value, MPFR_RNDN);
224 return result;
225}
226
229 HighPrecisionReal result(
230 std::max(mpfr_get_prec(value), mpfr_get_prec(other.value)));
231 mpfr_div(result.value, value, other.value, MPFR_RNDN);
232 return result;
233}
234
237 mpfr_add(value, value, other.value, MPFR_RNDN);
238 return *this;
239}
240
243 mpfr_sub(value, value, other.value, MPFR_RNDN);
244 return *this;
245}
246
249 mpfr_mul(value, value, other.value, MPFR_RNDN);
250 return *this;
251}
252
255 mpfr_div(value, value, other.value, MPFR_RNDN);
256 return *this;
257}
258
259// Comparison operators
261 return mpfr_equal_p(value, other.value) != 0;
262}
263
265 return !(*this == other);
266}
267
269 return mpfr_less_p(value, other.value) != 0;
270}
271
273 return mpfr_lessequal_p(value, other.value) != 0;
274}
275
277 return mpfr_greater_p(value, other.value) != 0;
278}
279
281 return mpfr_greaterequal_p(value, other.value) != 0;
282}
283
284// Other operations
286 HighPrecisionReal result(mpfr_get_prec(value));
287 mpfr_abs(result.value, value, MPFR_RNDN);
288 return result;
289}
290
292 if (*this < HighPrecisionReal(0)) {
293 throw std::domain_error("Cannot compute square root of a negative number");
294 }
295 HighPrecisionReal result(mpfr_get_prec(value));
296 mpfr_sqrt(result.value, value, MPFR_RNDN);
297 return result;
298}
299
301 if (*this < HighPrecisionReal(0)) {
302 return HighPrecisionReal(0);
303 }
304 return sqrt();
305}
306
308 HighPrecisionReal result(
309 std::max(mpfr_get_prec(value), mpfr_get_prec(exp.value)));
310 mpfr_pow(result.value, value, exp.value, MPFR_RNDN);
311 return result;
312}
313
314// Rounding operations
316 HighPrecisionReal result(mpfr_get_prec(value));
317 mpfr_ceil(result.value, value);
318 return result;
319}
320
322 HighPrecisionReal result(mpfr_get_prec(value));
323 mpfr_floor(result.value, value);
324 return result;
325}
326
328 HighPrecisionReal result(mpfr_get_prec(value));
329 mpfr_round(result.value, value);
330 return result;
331}
332
333// Exponential and logarithmic functions
335 HighPrecisionReal result(mpfr_get_prec(value));
336 mpfr_exp(result.value, value, MPFR_RNDN);
337 return result;
338}
339
341 if (*this <= HighPrecisionReal(0)) {
342 throw std::domain_error(
343 "Cannot compute logarithm of a non-positive number");
344 }
345 HighPrecisionReal result(mpfr_get_prec(value));
346 mpfr_log(result.value, value, MPFR_RNDN);
347 return result;
348}
349
351 if (*this <= HighPrecisionReal(0)) {
352 throw std::domain_error(
353 "Cannot compute logarithm of a non-positive number");
354 }
355 HighPrecisionReal result(mpfr_get_prec(value));
356 mpfr_log10(result.value, value, MPFR_RNDN);
357 return result;
358}
359
361 if (*this <= HighPrecisionReal(0)) {
362 throw std::domain_error(
363 "Cannot compute logarithm of a non-positive number");
364 }
365 HighPrecisionReal result(mpfr_get_prec(value));
366 mpfr_log2(result.value, value, MPFR_RNDN);
367 return result;
368}
369
371 if (*this <= HighPrecisionReal(0) || base <= HighPrecisionReal(0) ||
372 base == HighPrecisionReal(1)) {
373 throw std::domain_error("Invalid arguments for logarithm");
374 }
375 HighPrecisionReal result = ln();
376 HighPrecisionReal baseLog = base.ln();
377 mpfr_div(result.value, result.value, baseLog.value, MPFR_RNDN);
378 return result;
379}
380
381// Trigonometric functions
383 HighPrecisionReal result(mpfr_get_prec(value));
384 mpfr_sin(result.value, value, MPFR_RNDN);
385 return result;
386}
387
389 HighPrecisionReal result(mpfr_get_prec(value));
390 mpfr_cos(result.value, value, MPFR_RNDN);
391 return result;
392}
393
395 HighPrecisionReal result(mpfr_get_prec(value));
396 mpfr_tan(result.value, value, MPFR_RNDN);
397 return result;
398}
399
401 HighPrecisionReal result(mpfr_get_prec(value));
402 mpfr_cot(result.value, value, MPFR_RNDN);
403 return result;
404}
405
407 HighPrecisionReal result(mpfr_get_prec(value));
408 mpfr_sec(result.value, value, MPFR_RNDN);
409 return result;
410}
411
413 HighPrecisionReal result(mpfr_get_prec(value));
414 mpfr_csc(result.value, value, MPFR_RNDN);
415 return result;
416}
417
419 if (*this < HighPrecisionReal(-1) || *this > HighPrecisionReal(1)) {
420 throw std::domain_error("Argument for asin must be in range [-1, 1]");
421 }
422 HighPrecisionReal result(mpfr_get_prec(value));
423 mpfr_asin(result.value, value, MPFR_RNDN);
424 return result;
425}
426
428 if (*this < HighPrecisionReal(-1) || *this > HighPrecisionReal(1)) {
429 throw std::domain_error("Argument for acos must be in range [-1, 1]");
430 }
431 HighPrecisionReal result(mpfr_get_prec(value));
432 mpfr_acos(result.value, value, MPFR_RNDN);
433 return result;
434}
435
437 HighPrecisionReal result(mpfr_get_prec(value));
438 mpfr_atan(result.value, value, MPFR_RNDN);
439 return result;
440}
441
443 // acot(x) = π/2 - atan(x)
444 HighPrecisionReal result(mpfr_get_prec(value));
445 HighPrecisionReal pi_half = pi(mpfr_get_prec(value)) / HighPrecisionReal(2);
446 HighPrecisionReal atan_val = atan();
447 mpfr_sub(result.value, pi_half.value, atan_val.value, MPFR_RNDN);
448 return result;
449}
450
452 // asec(x) = acos(1/x)
453 if (*this == HighPrecisionReal(0)) {
454 throw std::domain_error("Argument for asec cannot be 0");
455 }
456 HighPrecisionReal reciprocal(mpfr_get_prec(value));
457 mpfr_ui_div(reciprocal.value, 1, value, MPFR_RNDN);
458 return reciprocal.acos();
459}
460
462 // acsc(x) = asin(1/x)
463 if (*this == HighPrecisionReal(0)) {
464 throw std::domain_error("Argument for acsc cannot be 0");
465 }
466 HighPrecisionReal reciprocal(mpfr_get_prec(value));
467 mpfr_ui_div(reciprocal.value, 1, value, MPFR_RNDN);
468 return reciprocal.asin();
469}
470
472 const HighPrecisionReal &x) {
473 mpfr_prec_t precision =
474 std::max(mpfr_get_prec(y.value), mpfr_get_prec(x.value));
475 HighPrecisionReal result(precision);
476 mpfr_atan2(result.value, y.value, x.value, MPFR_RNDN);
477 return result;
478}
479
480// Hyperbolic functions
482 HighPrecisionReal result(mpfr_get_prec(value));
483 mpfr_sinh(result.value, value, MPFR_RNDN);
484 return result;
485}
486
488 HighPrecisionReal result(mpfr_get_prec(value));
489 mpfr_cosh(result.value, value, MPFR_RNDN);
490 return result;
491}
492
494 HighPrecisionReal result(mpfr_get_prec(value));
495 mpfr_tanh(result.value, value, MPFR_RNDN);
496 return result;
497}
498
500 HighPrecisionReal result(mpfr_get_prec(value));
501 mpfr_coth(result.value, value, MPFR_RNDN);
502 return result;
503}
504
506 HighPrecisionReal result(mpfr_get_prec(value));
507 mpfr_sech(result.value, value, MPFR_RNDN);
508 return result;
509}
510
512 HighPrecisionReal result(mpfr_get_prec(value));
513 mpfr_csch(result.value, value, MPFR_RNDN);
514 return result;
515}
516
518 HighPrecisionReal result(mpfr_get_prec(value));
519 mpfr_asinh(result.value, value, MPFR_RNDN);
520 return result;
521}
522
524 if (*this < HighPrecisionReal(1)) {
525 throw std::domain_error("Argument for acosh must be >= 1");
526 }
527 HighPrecisionReal result(mpfr_get_prec(value));
528 mpfr_acosh(result.value, value, MPFR_RNDN);
529 return result;
530}
531
533 if (*this <= HighPrecisionReal(-1) || *this >= HighPrecisionReal(1)) {
534 throw std::domain_error("Argument for atanh must be in range (-1, 1)");
535 }
536 HighPrecisionReal result(mpfr_get_prec(value));
537 mpfr_atanh(result.value, value, MPFR_RNDN);
538 return result;
539}
540
542 // acoth(x) = atanh(1/x)
543 if (*this >= HighPrecisionReal(-1) && *this <= HighPrecisionReal(1)) {
544 throw std::domain_error("Argument for acoth must be outside range [-1, 1]");
545 }
546 HighPrecisionReal reciprocal(mpfr_get_prec(value));
547 mpfr_ui_div(reciprocal.value, 1, value, MPFR_RNDN);
548 return reciprocal.atanh();
549}
550
552 if (*this <= HighPrecisionReal(0) || *this > HighPrecisionReal(1)) {
553 throw std::domain_error("Argument for asech must be in range (0, 1]");
554 }
555 // asech(x) = acosh(1/x)
556 HighPrecisionReal reciprocal(mpfr_get_prec(value));
557 mpfr_ui_div(reciprocal.value, 1, value, MPFR_RNDN);
558 return reciprocal.acosh();
559}
560
562 if (*this == HighPrecisionReal(0)) {
563 throw std::domain_error("Argument for acsch cannot be 0");
564 }
565 // acsch(x) = asinh(1/x)
566 HighPrecisionReal reciprocal(mpfr_get_prec(value));
567 mpfr_ui_div(reciprocal.value, 1, value, MPFR_RNDN);
568 return reciprocal.asinh();
569}
570
571bool HighPrecisionReal::isNaN() const { return mpfr_nan_p(value) != 0; }
572
573// Conversion functions
574std::string HighPrecisionReal::toString() const {
575 // for integer, output decimal directly, without scientific notation;
576 // for other cases, output at most 17 significant digits, unless the exponent
577 // is too large.
578
579 // 1. NaN / Inf
580 if (mpfr_nan_p(value))
581 return "NaN";
582 if (mpfr_inf_p(value))
583 return mpfr_sgn(value) < 0 ? "-inf" : "inf";
584
585 // 2. integer: %.0Rf
586 char *buf = nullptr;
587 if (mpfr_integer_p(value)) {
588 mpfr_asprintf(&buf, "%.0Rf", value); // No fractional part
589 }
590 else {
591 // 3. non-integer: output at most 17 significant digits, if the exponent is
592 // in [-6,6] use f, otherwise use g get the exponent
593 mpfr_exp_t exp10;
594 mpfr_get_str(nullptr, &exp10, 10, 0, value, MPFR_RNDN);
595 if (exp10 >= -6 && exp10 <= 6) {
596 // fixed decimal format, keep enough significant digits
597 mpfr_asprintf(&buf, "%.17Rf", value);
598 // remove trailing zeros and decimal point
599 std::string tmp(buf);
600 mpfr_free_str(buf);
601 // remove trailing zeros
602 while (tmp.size() > 1 && tmp.back() == '0')
603 tmp.pop_back();
604 if (!tmp.empty() && tmp.back() == '.')
605 tmp.pop_back();
606 return tmp;
607 }
608 else {
609 mpfr_asprintf(
610 &buf, "%.17Rg",
611 value); // scientific notation, but control significant digits
612 }
613 }
614 std::string s(buf);
615 mpfr_free_str(buf);
616 return s;
617}
618
620 std::string str = toString();
621 return std::stod(str);
622}
623
625 std::string str = toString();
626 return std::stof(str);
627}
628
629int HighPrecisionReal::toInt() const { return mpfr_get_si(value, MPFR_RNDN); }
630
632 mpz_t z;
633 mpz_init(z);
634 mpfr_get_z(z, value, MPFR_RNDN);
635 Integer result(z);
636 mpz_clear(z);
637 return result;
638}
639
641 // MPFR doesn't have a direct mpfr_get_ll function, so we'll use a workaround
642 // First convert to integer, then to long long
643 mpz_t z;
644 mpz_init(z);
645 mpfr_get_z(z, value, MPFR_RNDN);
646
647 // Get the value as a long long
648 long long result;
649 if (mpz_fits_slong_p(z)) {
650 result = mpz_get_si(z);
651 }
652 else {
653 // Handle values that are too large
654 if (mpz_sgn(z) >= 0) {
655 result = LLONG_MAX; // Maximum long long value
656 }
657 else {
658 result = LLONG_MIN; // Minimum long long value
659 }
660 }
661
662 mpz_clear(z);
663 return result;
664}
665
666// Set and get precision
667void HighPrecisionReal::setPrecision(mpfr_prec_t precision) {
668 mpfr_prec_round(value, precision, MPFR_RNDN);
669}
670
672 return mpfr_get_prec(value);
673}
674
675bool HighPrecisionReal::isInteger() const { return mpfr_integer_p(value); }
676
677// Access internal MPFR value
678mpfr_ptr HighPrecisionReal::getMPFR() { return value; }
679
680mpfr_srcptr HighPrecisionReal::getMPFR() const { return value; }
681
683 HighPrecisionReal result(mpfr_get_prec(value));
684 mpfr_set(result.value, value, MPFR_RNDN);
685 mpfr_nextbelow(result.value);
686 return result;
687}
688
690 HighPrecisionReal result(mpfr_get_prec(value));
691 mpfr_set(result.value, value, MPFR_RNDN);
692 mpfr_nextabove(result.value);
693 return result;
694}
695
696bool HighPrecisionReal::isInfinity() const { return mpfr_inf_p(value) != 0; }
697
699 return mpfr_inf_p(value) != 0 && mpfr_sgn(value) < 0;
700}
701
703 return mpfr_inf_p(value) != 0 && mpfr_sgn(value) > 0;
704}
705
706// -------------HighPrecisionInteger-------------
708 mpz_set(value.get_mpz_t(), z);
709}
710
712 return (const mpz_t *)value.get_mpz_t();
713}
714
715// Static methods
717 HighPrecisionInteger result(1);
718 for (unsigned long i = 2; i <= n; ++i) {
719 result *= HighPrecisionInteger(i);
720 }
721 return result;
722}
723
725 if (n <= 1)
726 return HighPrecisionInteger(n);
730 for (unsigned long i = 2; i <= n; ++i) {
731 c = a + b;
732 a = b;
733 b = c;
734 }
735 return b;
736}
737
739 const HighPrecisionInteger &b) {
741 mpz_gcd(result.value.get_mpz_t(), a.value.get_mpz_t(), b.value.get_mpz_t());
742 return result;
743}
744
746 const HighPrecisionInteger &b) {
748 mpz_lcm(result.value.get_mpz_t(), a.value.get_mpz_t(), b.value.get_mpz_t());
749 return result;
750}
751
752// Constructors
754
756
758
759HighPrecisionInteger::HighPrecisionInteger(unsigned long i) : value(i) {}
760
762 : value(std::to_string(i)) {}
763
765
766HighPrecisionInteger::HighPrecisionInteger(const std::string &s, int base) {
767 try {
768 value = mpz_class(s, base);
769 }
770 catch (const std::exception &e) {
771 throw std::invalid_argument(
772 "Cannot convert string to high precision integer");
773 }
774}
775
777 try {
778 value = mpz_class(s, base);
779 }
780 catch (const std::exception &e) {
781 throw std::invalid_argument(
782 "Cannot convert string to high precision integer");
783 }
784}
785
787 : value(other.value) {}
788
789// Assignment operator
792 if (this != &other) {
793 value = other.value;
794 }
795 return *this;
796}
797
798// Basic arithmetic operators
802 result.value = value + other.value;
803 return result;
804}
805
809 result.value = value - other.value;
810 return result;
811}
812
815 result.value = -value;
816 return result;
817}
818
822 result.value = value * other.value;
823 return result;
824}
825
828 if (other.value == 0) {
829 throw std::domain_error("Division by zero");
830 }
832 result.value = value / other.value;
833 return result;
834}
835
838 if (other.value == 0) {
839 throw std::domain_error("Modulo by zero");
840 }
842 result.value = value % other.value;
843 return result;
844}
845
848 value += other.value;
849 return *this;
850}
851
854 value -= other.value;
855 return *this;
856}
857
860 value *= other.value;
861 return *this;
862}
863
866 if (other.value == 0) {
867 throw std::domain_error("Division by zero");
868 }
869 value /= other.value;
870 return *this;
871}
872
875 if (other.value == 0) {
876 throw std::domain_error("Modulo by zero");
877 }
878 value %= other.value;
879 return *this;
880}
881
882// Increment/decrement operators
887
889 HighPrecisionInteger temp(*this);
890 ++value;
891 return temp;
892}
893
898
900 HighPrecisionInteger temp(*this);
901 --value;
902 return temp;
903}
904
905// Comparison operators
907 return value == other.value;
908}
909
911 return value != other.value;
912}
913
915 return value < other.value;
916}
917
919 return value <= other.value;
920}
921
923 return value > other.value;
924}
925
927 return value >= other.value;
928}
929
930// Bitwise operators
934 mpz_and(result.value.get_mpz_t(), value.get_mpz_t(), other.value.get_mpz_t());
935 return result;
936}
937
941 mpz_ior(result.value.get_mpz_t(), value.get_mpz_t(), other.value.get_mpz_t());
942 return result;
943}
944
948 mpz_xor(result.value.get_mpz_t(), value.get_mpz_t(), other.value.get_mpz_t());
949 return result;
950}
951
954 mpz_com(result.value.get_mpz_t(), value.get_mpz_t());
955 return result;
956}
957
959HighPrecisionInteger::operator<<(unsigned long bits) const {
961 mpz_mul_2exp(result.value.get_mpz_t(), value.get_mpz_t(), bits);
962 return result;
963}
964
966HighPrecisionInteger::operator>>(unsigned long bits) const {
968 mpz_fdiv_q_2exp(result.value.get_mpz_t(), value.get_mpz_t(), bits);
969 return result;
970}
971
972// Other operations
975 mpz_abs(result.value.get_mpz_t(), value.get_mpz_t());
976 return result;
977}
978
981 mpz_pow_ui(result.value.get_mpz_t(), value.get_mpz_t(), exp);
982 return result;
983}
984
986 if (*this < HighPrecisionInteger(0)) {
987 throw std::domain_error("Cannot compute square root of a negative number");
988 }
990 mpz_sqrt(result.value.get_mpz_t(), value.get_mpz_t());
991 return result;
992}
993
995 if (*this < HighPrecisionInteger(0)) {
996 return HighPrecisionInteger(0);
997 }
999 mpz_sqrt(result.value.get_mpz_t(), value.get_mpz_t());
1000 return result;
1001}
1003 if (n == 0) {
1004 throw std::domain_error("Cannot compute zeroth root");
1005 }
1006 if (*this < HighPrecisionInteger(0) && n % 2 == 0) {
1007 throw std::domain_error("Cannot compute even root of a negative number");
1008 }
1009 HighPrecisionInteger result;
1010 mpz_root(result.value.get_mpz_t(), value.get_mpz_t(), n);
1011 return result;
1012}
1013
1015 return mpz_probab_prime_p(value.get_mpz_t(), reps) > 0;
1016}
1017
1019 if (d.value == 0) {
1020 throw std::domain_error("Cannot check divisibility by zero");
1021 }
1022 return mpz_divisible_p(value.get_mpz_t(), d.value.get_mpz_t()) != 0;
1023}
1024
1025// Conversion functions
1026std::string HighPrecisionInteger::toString(int base) const {
1027 if (base < 2 || base > 62) {
1028 throw std::invalid_argument("Base must be between 2 and 62");
1029 }
1030 char *str = mpz_get_str(nullptr, base, value.get_mpz_t());
1031 std::string result(str);
1032 free(str);
1033 return result;
1034}
1035
1037 if (value > INT_MAX || value < INT_MIN) {
1038 throw std::overflow_error("Value does not fit in int");
1039 }
1040 return value.get_si();
1041}
1042
1044 if (!mpz_fits_slong_p(value.get_mpz_t())) {
1045 throw std::overflow_error("Value does not fit in long");
1046 }
1047 return value.get_si();
1048}
1049
1050unsigned long HighPrecisionInteger::toULong() const {
1051 if (value < 0 || !mpz_fits_ulong_p(value.get_mpz_t())) {
1052 throw std::overflow_error("Value does not fit in unsigned long");
1053 }
1054 return value.get_ui();
1055}
1056
1058 // GMP doesn't directly support conversion to long long
1059 // We'll use string conversion for very large numbers
1060 if (mpz_fits_slong_p(value.get_mpz_t())) {
1061 return value.get_si();
1062 }
1063 else {
1064 try {
1065 return std::stoll(toString(10));
1066 }
1067 catch (const std::exception &e) {
1068 throw std::overflow_error("Value does not fit in long long");
1069 }
1070 }
1071}
1072
1073double HighPrecisionInteger::toDouble() const { return value.get_d(); }
1074
1075// Access internal GMP value
1076const mpz_class &HighPrecisionInteger::getMPZ() const { return value; }
1077
1078mpz_class &HighPrecisionInteger::getMPZ() { return value; }
1079
1081 HighPrecisionInteger result;
1082 result.value = value - 1;
1083 return result;
1084}
1085
1087 HighPrecisionInteger result;
1088 result.value = value + 1;
1089 return result;
1090}
1091
1092// -------------Number-------------
1093// Constructor
1094Number::Number() : type(INT_TYPE), intValue(0) {}
1095
1096Number::Number(const HighPrecisionInteger &i) : type(INT_TYPE), intValue(i) {}
1097
1098Number::Number(const HighPrecisionReal &r) : type(REAL_TYPE), realValue(r) {}
1099
1100Number::Number(int i) : type(INT_TYPE), intValue(i) {}
1101
1102Number::Number(double d, bool asInteger) {
1103 if (asInteger) {
1104 type = INT_TYPE;
1106 }
1107 else {
1108 type = REAL_TYPE;
1110 }
1111}
1112
1113Number::Number(const std::string &s, bool asInteger) {
1114 if (asInteger) {
1115 type = INT_TYPE;
1117 }
1118 else {
1119 type = REAL_TYPE;
1121 }
1122}
1123
1124Number::Number(const Number &other) : type(other.type) {
1125 if (type == INT_TYPE) {
1126 intValue = other.intValue;
1127 }
1128 else {
1129 realValue = other.realValue;
1130 }
1131}
1132
1133// Assignment operator
1135 if (this != &other) {
1136 type = other.type;
1137 if (type == INT_TYPE) {
1138 intValue = other.intValue;
1139 }
1140 else {
1141 realValue = other.realValue;
1142 }
1143 }
1144 return *this;
1145}
1146
1147// Destructor
1149 // No special handling needed, HighPrecisionInteger and HighPrecisionReal will
1150 // clean up automatically
1151}
1152
1153// Get value
1155 if (type != INT_TYPE) {
1156 throw std::runtime_error("Number is not an integer");
1157 }
1158 return intValue;
1159}
1160
1162 if (type != REAL_TYPE) {
1163 throw std::runtime_error("Number is not a real");
1164 }
1165 return realValue;
1166}
1167
1168// Type conversion
1170 if (type == INT_TYPE) {
1171 return intValue;
1172 }
1173 else {
1174 return realValue.toInteger();
1175 }
1176}
1177
1178HighPrecisionReal Number::toReal(mpfr_prec_t precision) const {
1179 if (type == REAL_TYPE) {
1180 return realValue;
1181 }
1182 else {
1183 return HighPrecisionReal(intValue, precision);
1184 }
1185}
1186
1187Number Number::zero() { return Number(0, false); }
1188Number Number::one() { return Number(1, false); }
1190 Number result;
1191 mpfr_set_inf(result.realValue.getMPFR(), 1);
1192 return result;
1193}
1195 Number result;
1196 mpfr_set_inf(result.realValue.getMPFR(), -1);
1197 return result;
1198}
1200 Number result;
1201 mpfr_set_inf(result.realValue.getMPFR(), 1);
1202 return result;
1203}
1204bool Number::isZero() const {
1205 if (type == INT_TYPE) {
1206 return intValue == 0;
1207 }
1208 return realValue == 0;
1209}
1210bool Number::isOne() const {
1211 if (type == INT_TYPE) {
1212 return intValue == 1;
1213 }
1214 return realValue == 1;
1215}
1217 if (type == INT_TYPE) {
1218 return false;
1219 }
1220 return realValue.isInfinity();
1221}
1222
1224 if (type == INT_TYPE) {
1225 return false;
1226 }
1228}
1230 if (type == INT_TYPE) {
1231 return false;
1232 }
1234}
1235Number Number::pi(size_t precision) {
1236 return Number(HighPrecisionReal::pi(precision));
1237}
1238Number Number::e(size_t precision) {
1239 return Number(HighPrecisionReal::e(precision));
1240}
1241Number Number::phi(size_t precision) {
1242 return Number(HighPrecisionReal::phi(precision));
1243}
1244Number Number::ln2(size_t precision) {
1245 return Number(HighPrecisionReal::ln2(precision));
1246}
1247Number Number::ln10(size_t precision) {
1248 return Number(HighPrecisionReal::ln10(precision));
1249}
1250Number Number::log2_e(size_t precision) {
1251 return Number(HighPrecisionReal::log2_e(precision));
1252}
1253Number Number::log10_e(size_t precision) {
1254 return Number(HighPrecisionReal::log10_e(precision));
1255}
1256Number Number::epsilon(size_t precision) {
1257 return Number(HighPrecisionReal::epsilon(precision));
1258}
1259
1260// Basic operations
1261Number Number::operator+(const Number &other) const {
1262 // If both are integers, the result is an integer
1263 if (type == INT_TYPE && other.type == INT_TYPE) {
1264 return Number(intValue + other.intValue);
1265 }
1266 // Otherwise, the result is a real number
1267 return Number(toReal() + other.toReal());
1268}
1269
1270Number Number::operator-(const Number &other) const {
1271 if (type == INT_TYPE && other.type == INT_TYPE) {
1272 return Number(intValue - other.intValue);
1273 }
1274 return Number(toReal() - other.toReal());
1275}
1276
1278 if (type == INT_TYPE) {
1279 return Number(-intValue);
1280 }
1281 return Number(-realValue);
1282}
1283
1284Number Number::operator*(const Number &other) const {
1285 if (type == INT_TYPE && other.type == INT_TYPE) {
1286 return Number(intValue * other.intValue);
1287 }
1288 return Number(toReal() * other.toReal());
1289}
1290
1291Number Number::operator/(const Number &other) const {
1292 // Even if both operands are integers, the result may be a real number
1293 // You can choose to always return a real number, or return an integer when
1294 // divisible
1295 if (type == INT_TYPE && other.type == INT_TYPE) {
1296 if (intValue % other.intValue == HighPrecisionInteger(0)) {
1297 // Divisible
1298 return Number(intValue / other.intValue);
1299 }
1300 }
1301 return Number(toReal() / other.toReal());
1302}
1303
1304Number Number::operator%(const Number &other) const {
1305 condAssert(type == INT_TYPE && other.type == INT_TYPE,
1306 "Cannot compute modulo of non-integer numbers");
1307 return Number(intValue % other.intValue);
1308}
1309
1311 if (type == INT_TYPE && other.type == INT_TYPE) {
1312 intValue += other.intValue;
1313 }
1314 else {
1315 realValue += other.toReal();
1316 }
1317 return *this;
1318}
1319
1321 if (type == INT_TYPE && other.type == INT_TYPE) {
1322 intValue -= other.intValue;
1323 }
1324 else {
1325 realValue -= other.toReal();
1326 }
1327 return *this;
1328}
1329
1331 if (type == INT_TYPE && other.type == INT_TYPE) {
1332 intValue *= other.intValue;
1333 }
1334 else {
1335 realValue *= other.toReal();
1336 }
1337 return *this;
1338}
1339
1341 if (type == INT_TYPE && other.type == INT_TYPE) {
1342 intValue /= other.intValue;
1343 }
1344 else {
1345 realValue /= other.toReal();
1346 }
1347 return *this;
1348}
1349
1351 condAssert(type == INT_TYPE && other.type == INT_TYPE,
1352 "Cannot compute modulo of non-integer numbers");
1353 intValue %= other.intValue;
1354 return *this;
1355}
1356
1358 if (type == INT_TYPE) {
1359 intValue++;
1360 }
1361 else {
1362 realValue = realValue + 1;
1363 }
1364 return *this;
1365}
1367 Number temp = *this;
1368 operator++();
1369 return temp;
1370}
1372 if (type == INT_TYPE) {
1373 intValue--;
1374 }
1375 else {
1376 realValue = realValue - 1;
1377 }
1378 return *this;
1379}
1381 Number temp = *this;
1382 operator--();
1383 return temp;
1384}
1385
1386// Comparison operators
1387bool Number::operator==(const Number &other) const {
1388 if (type == other.type) {
1389 if (type == INT_TYPE) {
1390 return intValue == other.intValue;
1391 }
1392 else {
1393 return realValue == other.realValue;
1394 }
1395 }
1396 // When types are different, convert to real for comparison
1397 return toReal() == other.toReal();
1398}
1399
1400bool Number::operator!=(const Number &other) const { return !(*this == other); }
1401
1402bool Number::operator<(const Number &other) const {
1403 if (type == other.type) {
1404 if (type == INT_TYPE) {
1405 return intValue < other.intValue;
1406 }
1407 else {
1408 return realValue < other.realValue;
1409 }
1410 }
1411 return toReal() < other.toReal();
1412}
1413
1414bool Number::operator<=(const Number &other) const {
1415 if (type == other.type) {
1416 if (type == INT_TYPE) {
1417 return intValue <= other.intValue;
1418 }
1419 else {
1420 return realValue <= other.realValue;
1421 }
1422 }
1423 return toReal() <= other.toReal();
1424}
1425
1426bool Number::operator>(const Number &other) const { return !(*this <= other); }
1427
1428bool Number::operator>=(const Number &other) const { return !(*this < other); }
1429
1430// Convert to string
1431std::string Number::toString() const {
1432 if (type == INT_TYPE) {
1433 return intValue.toString();
1434 }
1435 else {
1436 return realValue.toString();
1437 }
1438}
1439
1440// Mathematical functions
1442 if (type == INT_TYPE) {
1443 return Number(intValue.abs());
1444 }
1445 else {
1446 return Number(realValue.abs());
1447 }
1448}
1449
1451 // For perfect square integers, you can return an integer result
1452 if (type == INT_TYPE) {
1454 return Number(root);
1455 }
1456 // Otherwise, return a real number
1457 return Number(toReal().sqrt());
1458}
1459
1461 if (type == INT_TYPE) {
1463 return Number(root);
1464 }
1465 return Number(toReal().safeSqrt());
1466}
1467
1468Number Number::pow(const Number &exp) const {
1469 // If the exponent is an integer and the base is also an integer
1470 if (type == INT_TYPE && exp.type == INT_TYPE) {
1471 // If the exponent is a non-negative integer, you can use integer power
1472 if (exp.intValue >= HighPrecisionInteger(0)) {
1473 try {
1474 unsigned long expVal = exp.intValue.toULong();
1475 return Number(intValue.pow(expVal));
1476 }
1477 catch (const std::overflow_error &) {
1478 // The exponent is too large, use real calculation
1479 }
1480 }
1481 }
1482 // Otherwise, use real calculation
1483 return Number(toReal().pow(exp.toReal()));
1484}
1485
1486// Rounding operations
1488 if (type == INT_TYPE) {
1489 return Number(intValue);
1490 }
1491 else {
1492 return Number(realValue.ceil());
1493 }
1494}
1495
1497 if (type == INT_TYPE) {
1498 return Number(intValue);
1499 }
1500 else {
1501 return Number(realValue.floor());
1502 }
1503}
1504
1506 if (type == INT_TYPE) {
1507 return Number(intValue);
1508 }
1509 else {
1510 return Number(realValue.round());
1511 }
1512}
1513
1514// Exponential and logarithmic functions
1517 if (type == INT_TYPE) {
1519 }
1520 return Number(val.exp());
1521}
1524 if (type == INT_TYPE) {
1526 }
1527 return Number(val.ln());
1528}
1531 if (type == INT_TYPE) {
1533 }
1534 return Number(val.lg());
1535}
1538 if (type == INT_TYPE) {
1540 }
1541 return Number(val.lb());
1542}
1543Number Number::log(const Number &base) const {
1545 if (type == INT_TYPE) {
1547 }
1548 return Number(val.log(base.toReal()));
1549}
1550
1551// Trigonometric functions
1554 if (type == INT_TYPE) {
1556 }
1557 return Number(val.sin());
1558}
1561 if (type == INT_TYPE) {
1563 }
1564 return Number(val.cos());
1565}
1568 if (type == INT_TYPE) {
1570 }
1571 return Number(val.tan());
1572}
1575 if (type == INT_TYPE) {
1577 }
1578 return Number(val.cot());
1579}
1582 if (type == INT_TYPE) {
1584 }
1585 return Number(val.sec());
1586}
1589 if (type == INT_TYPE) {
1591 }
1592 return Number(val.csc());
1593}
1596 if (type == INT_TYPE) {
1598 }
1599 return Number(val.asin());
1600}
1603 if (type == INT_TYPE) {
1605 }
1606 return Number(val.acos());
1607}
1610 if (type == INT_TYPE) {
1612 }
1613 return Number(val.atan());
1614}
1617 if (type == INT_TYPE) {
1619 }
1620 return Number(val.acot());
1621}
1624 if (type == INT_TYPE) {
1626 }
1627 return Number(val.asec());
1628}
1631 if (type == INT_TYPE) {
1633 }
1634 return Number(val.acsc());
1635}
1636Number Number::atan2(const Number &y, const Number &x) {
1637 return Number(HighPrecisionReal::atan2(y.toReal(), x.toReal()));
1638}
1639
1640// Hyperbolic functions
1643 if (type == INT_TYPE) {
1645 }
1646 return Number(val.sinh());
1647}
1650 if (type == INT_TYPE) {
1652 }
1653 return Number(val.cosh());
1654}
1657 if (type == INT_TYPE) {
1659 }
1660 return Number(val.tanh());
1661}
1664 if (type == INT_TYPE) {
1666 }
1667 return Number(val.coth());
1668}
1671 if (type == INT_TYPE) {
1673 }
1674 return Number(val.sech());
1675}
1678 if (type == INT_TYPE) {
1680 }
1681 return Number(val.csch());
1682}
1685 if (type == INT_TYPE) {
1687 }
1688 return Number(val.asinh());
1689}
1692 if (type == INT_TYPE) {
1694 }
1695 return Number(val.acosh());
1696}
1699 if (type == INT_TYPE) {
1701 }
1702 return Number(val.atanh());
1703}
1706 if (type == INT_TYPE) {
1708 }
1709 return Number(val.tanh());
1710}
1713 if (type == INT_TYPE) {
1715 }
1716 return Number(val.acsch());
1717}
1720 if (type == INT_TYPE) {
1722 }
1723 return Number(val.acoth());
1724}
1726 if (type == INT_TYPE) {
1727 return Number(intValue.nextBelow());
1728 }
1729 else {
1730 return Number(realValue.nextBelow());
1731 }
1732}
1733
1735 if (type == INT_TYPE) {
1736 return Number(intValue.nextAbove());
1737 }
1738 else {
1739 return Number(realValue.nextAbove());
1740 }
1741}
1742
1743bool Number::isNaN() const {
1744 if (type == INT_TYPE) {
1745 return false;
1746 }
1747 return realValue.isNaN();
1748}
1749
1750} // namespace stabilizer::parser
#define condAssert(cond, msg)
Definition asserting.h:35
HighPrecisionInteger operator+(const HighPrecisionInteger &other) const
Definition number.cpp:800
HighPrecisionInteger & operator++()
Definition number.cpp:883
HighPrecisionInteger sqrt() const
Definition number.cpp:985
HighPrecisionInteger operator|(const HighPrecisionInteger &other) const
Definition number.cpp:939
bool operator>(const HighPrecisionInteger &other) const
Definition number.cpp:922
HighPrecisionInteger operator~() const
Definition number.cpp:952
static HighPrecisionInteger gcd(const HighPrecisionInteger &a, const HighPrecisionInteger &b)
Definition number.cpp:738
HighPrecisionInteger operator%(const HighPrecisionInteger &other) const
Definition number.cpp:837
HighPrecisionInteger root(unsigned long n) const
Definition number.cpp:1002
const mpz_class & getMPZ() const
Definition number.cpp:1076
HighPrecisionInteger & operator*=(const HighPrecisionInteger &other)
Definition number.cpp:859
bool isDivisibleBy(const HighPrecisionInteger &d) const
Definition number.cpp:1018
HighPrecisionInteger & operator+=(const HighPrecisionInteger &other)
Definition number.cpp:847
HighPrecisionInteger operator&(const HighPrecisionInteger &other) const
Definition number.cpp:932
bool isProbablePrime(int reps=25) const
Definition number.cpp:1014
HighPrecisionInteger operator^(const HighPrecisionInteger &other) const
Definition number.cpp:946
HighPrecisionInteger abs() const
Definition number.cpp:973
HighPrecisionInteger nextBelow() const
Definition number.cpp:1080
bool operator<=(const HighPrecisionInteger &other) const
Definition number.cpp:918
HighPrecisionInteger operator>>(unsigned long bits) const
Definition number.cpp:966
HighPrecisionInteger operator<<(unsigned long bits) const
Definition number.cpp:959
HighPrecisionInteger operator*(const HighPrecisionInteger &other) const
Definition number.cpp:820
HighPrecisionInteger safeSqrt() const
Definition number.cpp:994
bool operator<(const HighPrecisionInteger &other) const
Definition number.cpp:914
HighPrecisionInteger & operator%=(const HighPrecisionInteger &other)
Definition number.cpp:874
static HighPrecisionInteger factorial(unsigned long n)
Definition number.cpp:716
std::string toString(int base=10) const
Definition number.cpp:1026
bool operator==(const HighPrecisionInteger &other) const
Definition number.cpp:906
HighPrecisionInteger pow(unsigned long exp) const
Definition number.cpp:979
HighPrecisionInteger & operator--()
Definition number.cpp:894
HighPrecisionInteger operator-() const
Definition number.cpp:813
static HighPrecisionInteger lcm(const HighPrecisionInteger &a, const HighPrecisionInteger &b)
Definition number.cpp:745
bool operator>=(const HighPrecisionInteger &other) const
Definition number.cpp:926
HighPrecisionInteger nextAbove() const
Definition number.cpp:1086
HighPrecisionInteger & operator=(const HighPrecisionInteger &other)
Definition number.cpp:791
static HighPrecisionInteger fibonacci(unsigned long n)
Definition number.cpp:724
HighPrecisionInteger operator/(const HighPrecisionInteger &other) const
Definition number.cpp:827
bool operator!=(const HighPrecisionInteger &other) const
Definition number.cpp:910
HighPrecisionInteger & operator/=(const HighPrecisionInteger &other)
Definition number.cpp:865
HighPrecisionInteger & operator-=(const HighPrecisionInteger &other)
Definition number.cpp:853
HighPrecisionReal atanh() const
Definition number.cpp:532
static HighPrecisionReal ln10(mpfr_prec_t precision=128)
Definition number.cpp:73
HighPrecisionReal safeSqrt() const
Definition number.cpp:300
HighPrecisionReal ln() const
Definition number.cpp:340
HighPrecisionReal asinh() const
Definition number.cpp:517
void setPrecision(mpfr_prec_t precision)
Definition number.cpp:667
HighPrecisionReal tanh() const
Definition number.cpp:493
static HighPrecisionReal atan2(const HighPrecisionReal &y, const HighPrecisionReal &x)
Definition number.cpp:471
HighPrecisionReal acsc() const
Definition number.cpp:461
HighPrecisionReal sech() const
Definition number.cpp:505
HighPrecisionReal cot() const
Definition number.cpp:400
HighPrecisionReal abs() const
Definition number.cpp:285
HighPrecisionReal acosh() const
Definition number.cpp:523
HighPrecisionReal & operator+=(const HighPrecisionReal &other)
Definition number.cpp:236
HighPrecisionReal & operator/=(const HighPrecisionReal &other)
Definition number.cpp:254
bool operator!=(const HighPrecisionReal &other) const
Definition number.cpp:264
HighPrecisionReal asech() const
Definition number.cpp:551
HighPrecisionReal asec() const
Definition number.cpp:451
HighPrecisionReal & operator=(const HighPrecisionReal &other)
Definition number.cpp:181
bool operator<(const HighPrecisionReal &other) const
Definition number.cpp:268
static HighPrecisionReal euler(mpfr_prec_t precision=128)
Definition number.cpp:97
HighPrecisionReal operator*(const HighPrecisionReal &other) const
Definition number.cpp:220
static HighPrecisionReal epsilon(mpfr_prec_t precision=128)
Definition number.cpp:109
HighPrecisionReal acsch() const
Definition number.cpp:561
HighPrecisionReal acot() const
Definition number.cpp:442
HighPrecisionReal sqrt() const
Definition number.cpp:291
bool operator>=(const HighPrecisionReal &other) const
Definition number.cpp:280
HighPrecisionReal nextAbove() const
Definition number.cpp:689
HighPrecisionReal operator+(const HighPrecisionReal &other) const
Definition number.cpp:198
HighPrecisionReal sec() const
Definition number.cpp:406
HighPrecisionReal exp() const
Definition number.cpp:334
static HighPrecisionReal pi(mpfr_prec_t precision=128)
Definition number.cpp:42
bool operator==(const HighPrecisionReal &other) const
Definition number.cpp:260
HighPrecisionReal tan() const
Definition number.cpp:394
bool operator>(const HighPrecisionReal &other) const
Definition number.cpp:276
bool operator<=(const HighPrecisionReal &other) const
Definition number.cpp:272
HighPrecisionReal sin() const
Definition number.cpp:382
static HighPrecisionReal log2_e(mpfr_prec_t precision=128)
Definition number.cpp:80
HighPrecisionReal & operator-=(const HighPrecisionReal &other)
Definition number.cpp:242
HighPrecisionReal(mpfr_prec_t precision=128)
Definition number.cpp:123
HighPrecisionReal ceil() const
Definition number.cpp:315
HighPrecisionReal acos() const
Definition number.cpp:427
HighPrecisionReal cos() const
Definition number.cpp:388
HighPrecisionReal nextBelow() const
Definition number.cpp:682
HighPrecisionReal floor() const
Definition number.cpp:321
HighPrecisionReal operator/(const HighPrecisionReal &other) const
Definition number.cpp:228
HighPrecisionReal csch() const
Definition number.cpp:511
HighPrecisionReal asin() const
Definition number.cpp:418
static HighPrecisionReal log10_e(mpfr_prec_t precision=128)
Definition number.cpp:88
HighPrecisionReal atan() const
Definition number.cpp:436
HighPrecisionReal lg() const
Definition number.cpp:350
HighPrecisionReal lb() const
Definition number.cpp:360
HighPrecisionReal & operator*=(const HighPrecisionReal &other)
Definition number.cpp:248
static HighPrecisionReal phi(mpfr_prec_t precision=128)
Definition number.cpp:56
HighPrecisionReal pow(const HighPrecisionReal &exp) const
Definition number.cpp:307
HighPrecisionReal operator-() const
Definition number.cpp:213
static HighPrecisionReal e(mpfr_prec_t precision=128)
Definition number.cpp:48
HighPrecisionReal sinh() const
Definition number.cpp:481
static HighPrecisionReal catalan(mpfr_prec_t precision=128)
Definition number.cpp:103
HighPrecisionReal csc() const
Definition number.cpp:412
HighPrecisionReal log(const HighPrecisionReal &base) const
Definition number.cpp:370
HighPrecisionReal round() const
Definition number.cpp:327
static HighPrecisionReal ln2(mpfr_prec_t precision=128)
Definition number.cpp:67
HighPrecisionReal coth() const
Definition number.cpp:499
HighPrecisionReal acoth() const
Definition number.cpp:541
HighPrecisionReal cosh() const
Definition number.cpp:487
Number operator%(const Number &other) const
Definition number.cpp:1304
const HighPrecisionInteger & getInteger() const
Definition number.cpp:1154
Number pow(const Number &exp) const
Definition number.cpp:1468
bool operator!=(const Number &other) const
Definition number.cpp:1400
Number operator-() const
Definition number.cpp:1277
Number & operator%=(const Number &other)
Definition number.cpp:1350
Number & operator+=(const Number &other)
Definition number.cpp:1310
static Number infinity()
Definition number.cpp:1189
static Number ln10(size_t precision=128)
Definition number.cpp:1247
HighPrecisionInteger intValue
Definition number.h:433
std::string toString() const
Definition number.cpp:1431
Number & operator/=(const Number &other)
Definition number.cpp:1340
HighPrecisionInteger toInteger() const
Definition number.cpp:1169
bool operator>=(const Number &other) const
Definition number.cpp:1428
HighPrecisionReal toReal(mpfr_prec_t precision=128) const
Definition number.cpp:1178
HighPrecisionReal realValue
Definition number.h:434
static Number atan2(const Number &y, const Number &x)
Definition number.cpp:1636
static Number phi(size_t precision=128)
Definition number.cpp:1241
static Number log2_e(size_t precision=128)
Definition number.cpp:1250
bool isPositiveInfinity() const
Definition number.cpp:1229
bool operator<(const Number &other) const
Definition number.cpp:1402
bool operator==(const Number &other) const
Definition number.cpp:1387
bool operator>(const Number &other) const
Definition number.cpp:1426
static Number pi(size_t precision=128)
Definition number.cpp:1235
Number & operator=(const Number &other)
Definition number.cpp:1134
const HighPrecisionReal & getReal() const
Definition number.cpp:1161
Number & operator*=(const Number &other)
Definition number.cpp:1330
Number log(const Number &base) const
Definition number.cpp:1543
bool isNegativeInfinity() const
Definition number.cpp:1223
bool operator<=(const Number &other) const
Definition number.cpp:1414
Number operator+(const Number &other) const
Definition number.cpp:1261
static Number epsilon(size_t precision=128)
Definition number.cpp:1256
Number operator*(const Number &other) const
Definition number.cpp:1284
Number nextAbove() const
Definition number.cpp:1734
static Number e(size_t precision=128)
Definition number.cpp:1238
Number & operator-=(const Number &other)
Definition number.cpp:1320
static Number log10_e(size_t precision=128)
Definition number.cpp:1253
Number nextBelow() const
Definition number.cpp:1725
static Number ln2(size_t precision=128)
Definition number.cpp:1244
Number operator/(const Number &other) const
Definition number.cpp:1291
static Number positiveInfinity()
Definition number.cpp:1199
static Number negativeInfinity()
Definition number.cpp:1194
Number safeSqrt() const
Definition number.cpp:1460
Definition hash.h:27