LMCAS
Lamina Computer Algebra System
载入中...
搜索中...
未找到
rational.cpp
浏览该文件的文档.
1#include "rational.hpp"
2#include <stdexcept>
3
4namespace LMCAS {
5
6void Rational::simplify() {
7 if (!denominator) {
8 throw std::runtime_error("Denominator cannot be zero");
9 }
10
11 if (denominator.is_negative()) {
12 numerator = -numerator;
14 }
15
16 BigInt g = BigInt::gcd(numerator, denominator);
17 if (g != 0 && g != 1) {
18 numerator = numerator / g;
20 }
21}
22
23Rational::Rational(const BigInt& num, const BigInt& den) : numerator(num), denominator(den) {
24 simplify();
25}
26
27Rational::Rational(int num, int den) : numerator(num), denominator(den) {
28 simplify();
29}
30
31Rational Rational::operator+(const Rational& other) const {
32 BigInt new_num = numerator * other.denominator + other.numerator * denominator;
33 BigInt new_den = denominator * other.denominator;
34 return Rational(new_num, new_den);
35}
36
37Rational Rational::operator-(const Rational& other) const {
38 BigInt new_num = numerator * other.denominator - other.numerator * denominator;
39 BigInt new_den = denominator * other.denominator;
40 return Rational(new_num, new_den);
41}
42
43Rational Rational::operator*(const Rational& other) const {
44 BigInt new_num = numerator * other.numerator;
45 BigInt new_den = denominator * other.denominator;
46 return Rational(new_num, new_den);
47}
48
49Rational Rational::operator/(const Rational& other) const {
50 if (other.is_zero()) {
51 throw std::runtime_error("Division by zero");
52 }
53 BigInt new_num = numerator * other.denominator;
54 BigInt new_den = denominator * other.numerator;
55 return Rational(new_num, new_den);
56}
57
58Rational Rational::power(const BigInt& exponent) const {
59 if (exponent < BigInt(0)) {
60
61 if (is_zero()) {
62 throw std::runtime_error("Cannot raise zero to negative power");
63 }
64 BigInt pos_exp = -exponent;
65 return Rational(denominator.power(pos_exp), numerator.power(pos_exp));
66 }
67
68 if (!exponent) {
69 if (is_zero()) {
70 throw std::runtime_error("0^0 is undefined");
71 }
72 return Rational(1);
73 }
74
75 return Rational(numerator.power(exponent), denominator.power(exponent));
76}
77
78bool Rational::operator==(const Rational& other) const {
79 return numerator * other.denominator == other.numerator * denominator;
80}
81
82bool Rational::operator!=(const Rational& other) const {
83 return !(*this == other);
84}
85
86bool Rational::operator<(const Rational& other) const {
87 BigInt left = numerator * other.denominator;
88 BigInt right = other.numerator * denominator;
89 return left < right;
90}
91
92bool Rational::operator<=(const Rational& other) const {
93 return *this < other || *this == other;
94}
95
96bool Rational::operator>(const Rational& other) const {
97 return !(*this <= other);
98}
99
100bool Rational::operator>=(const Rational& other) const {
101 return !(*this < other);
102}
103
104Rational Rational::reciprocal() const {
105 if (is_zero()) {
106 throw std::runtime_error("Cannot take reciprocal of zero");
107 }
108 return Rational(denominator, numerator);
109}
110
111Rational Rational::abs() const {
112 Rational result = *this;
113 result.numerator = result.numerator.abs();
114 return result;
115}
116
117Rational Rational::operator-() const {
118 Rational result = *this;
119 result.numerator = -result.numerator;
120 return result;
121}
122
123}
bool is_zero(const SymbolicExpr &expression)
std::shared_ptr< SymbolicExpr > num(int value)
@ Rational
Rational numbers
ExprResult simplify(const ExprPtr &expression, ComputationContext &context)
const ExprPtr & exponent
const ExprPtr & right
const ExprPtr & denominator
精确有理数 Rational,基于 BigInt 分子/分母表示,自动约分。