LMCAS
Lamina Computer Algebra System
载入中...
搜索中...
未找到
rational.hpp
浏览该文件的文档.
1/**
2 * @file rational.hpp
3 * @brief 精确有理数 Rational,基于 BigInt 分子/分母表示,自动约分。
4 */
5#pragma once
6#include "bigint.hpp"
7#include "lmcas_export.hpp"
8#include "lmmc/config.h"
9#include <cstddef>
10#include <cstdint>
11#include <string>
12namespace LMCAS {
13
14/** @brief 精确有理数类,以 BigInt 分子/分母表示,构造时自动约分 */
15class LMCAS_API Rational {
16private:
17 static constexpr std::size_t max_literal_bytes = 1'048'576;
18 static constexpr std::size_t max_decimal_scale = 1'000'000;
19
20 BigInt numerator;
21 BigInt denominator;
22
23 static BigInt pow10(std::size_t exponent);
24
25 static std::size_t decimal_scale(std::int64_t exponent);
26
27 static bool power_leq(BigInt base, unsigned long exponent,
28 const BigInt& limit);
29
30 static BigInt integer_nth_root(const BigInt& value, unsigned long degree);
31
32 void simplify();
33
34public:
35
36 /** @brief 默认构造,值为 0 */
37 Rational() : numerator(0), denominator(1) {}
38
39 /**
40 * @brief 从 BigInt 构造整数有理数
41 * @param num 分子(分母为 1)
42 */
43 Rational(const BigInt& num) : numerator(num), denominator(1) {}
44
45 /**
46 * @brief 从分子分母构造有理数
47 * @param num 分子
48 * @param den 分母(不可为零)
49 */
50 Rational(const BigInt& num, const BigInt& den);
51
52 /**
53 * @brief 从 int 构造整数有理数
54 * @param num 整数值
55 */
56 Rational(int num) : numerator(num), denominator(1) {}
57
58 /**
59 * @brief 从 int 分子分母构造有理数
60 * @param num 分子
61 * @param den 分母
62 */
63 Rational(int num, int den);
64
65 /**
66 * @brief 从字符串构造有理数,支持小数、科学计数法、循环小数
67 * @param num 数字字符串
68 */
69 explicit Rational(const std::string& num);
70
71public:
72
73 /**
74 * @brief 从 double 构造精确有理数。
75 * @param value 有限的 binary64 浮点数值
76 * @return binary64 存储值对应的精确有理数,而非十进制显示文本的值
77 * @throws std::invalid_argument 若 value 为 NaN 或无穷大
78 */
79 static Rational from_double(double value);
80
81 /** @brief 获取分子 */
82 BigInt get_numerator() const { return numerator; }
83
84 /** @brief 获取分母 */
85 BigInt get_denominator() const { return denominator; }
86
87 /** @brief 判断是否为整数(分母为 1) */
88 bool is_integer() const {
89 return denominator == BigInt(1);
90 }
91
92 /** @brief 判断是否为零 */
93 bool is_zero() const {
94 return !numerator;
95 }
96
97 /**
98 * @brief 计算哈希值
99 * @return 哈希值
100 */
101 std::size_t hash() const;
102
103 /**
104 * @brief 转换为分数字符串(如 "3/4")
105 * @return 字符串表示
106 */
107 std::string to_string() const;
108
109 /**
110 * @brief 转换为十进制小数字符串(自动检测循环节)
111 * @return 小数字符串,循环部分用括号标记
112 */
113 std::string to_float_string();
114
115 /**
116 * @brief 转换为指定精度的十进制小数字符串
117 * @param n 小数位数(正数为小数点后位数,负数为整数部分截断位数)
118 * @return 定精度小数字符串
119 */
120 std::string to_float_string(std::int64_t n) const;
121
122 /**
123 * @brief 就地向零截断到指定十进制精度,区别于数学下取整。
124 * @param n 正数为小数位,零为整数位,负数为十进制整数位
125 * @throws std::length_error |n| 超过 1,000,000 时抛出,原值不变
126 */
127 void floor(const std::int64_t& n);
128
129private:
130
131 void floor_without_sim(const std::int64_t& n);
132
133public:
134
135 /**
136 * @brief 牛顿迭代法计算平方根(就地修改)
137 * @param n 精度位数
138 */
139 void sqrt_self(std::int64_t n);
140
141 /**
142 * @brief 计算平方根(返回新值)
143 * @param n 精度位数
144 * @return 平方根的有理近似
145 */
146 Rational sqrt(std::int64_t n) const;
147
148 /**
149 * @brief 牛顿迭代法计算 n 次方根(就地修改)
150 * @param radical 根次数
151 * @param n 精度位数
152 */
153 void radicand_self(const BigInt& radical, std::int64_t n);
154
155 /**
156 * @brief 计算 n 次方根(返回新值)
157 * @param radical 根次数
158 * @param n 精度位数
159 * @return n 次方根的有理近似
160 */
161 Rational radicand(const BigInt& radical, std::int64_t n);
162
163 /**
164 * @brief 转换为 BigInt(仅当为整数时有效)
165 * @return 对应的 BigInt
166 * @throw std::runtime_error 非整数时抛出
167 */
168 BigInt to_bigint() const;
169
170 /**
171 * @brief 转换为浮点数。
172 *
173 * 精确值可按 binary64 round-to-nearest 转为有限值时返回有限结果,
174 * 包括正负最大有限端点及其半 ULP 内邻域;
175 * 超出有限舍入范围或非零值下溢为零时抛出范围异常。
176 * @return 对应的 double 值
177 */
178 lmmc_real_t to_double() const;
179
180 /** @brief 有理数加法 */
181 Rational operator+(const Rational& other) const;
182
183 /** @brief 有理数减法 */
184 Rational operator-(const Rational& other) const;
185
186 /** @brief 有理数乘法 */
187 Rational operator*(const Rational& other) const;
188
189 /**
190 * @brief 有理数除法
191 * @param other 除数
192 * @return 商
193 * @throw std::runtime_error 除数为零时抛出
194 */
195 Rational operator/(const Rational& other) const;
196
197 /**
198 * @brief 有理数整数幂
199 * @param exponent 指数(可为负)
200 * @return this^exponent
201 * @throw std::runtime_error 零的负幂或 0^0 时抛出
202 */
203 Rational power(const BigInt& exponent) const;
204
205 /**
206 * @brief 有理数的有理数幂(就地修改)
207 * @param exponent 有理数指数
208 * @param n 精度位数
209 */
210 void power_self(const Rational& exponent, std::size_t n);
211
212 /**
213 * @brief 有理数的有理数幂(返回新值)
214 * @param exponent 有理数指数
215 * @param n 精度位数
216 * @return 结果的有理近似
217 */
218 Rational power(const Rational& exponent, std::size_t n);
219
220 bool operator==(const Rational& other) const;
221
222 bool operator!=(const Rational& other) const;
223
224 bool operator<(const Rational& other) const;
225
226 bool operator<=(const Rational& other) const;
227
228 bool operator>(const Rational& other) const;
229
230 bool operator>=(const Rational& other) const;
231
232 /**
233 * @brief 取倒数
234 * @return 1 / *this
235 * @throw std::runtime_error 零的倒数时抛出
236 */
237 Rational reciprocal() const;
238
239 /**
240 * @brief 取绝对值
241 * @return |*this|
242 */
243 Rational abs() const;
244
245 /** @brief 一元负号运算符 */
246 Rational operator-() const;
247};
248
249} // namespace LMCAS
任意精度整数 BigInt,底层调用 LMMP 实现高性能大数运算。
#define LMCAS_API
bool is_zero(const SymbolicExpr &expression)
std::shared_ptr< SymbolicExpr > num(int value)
@ Rational
Rational numbers
ExprResult simplify(const ExprPtr &expression, ComputationContext &context)
ExprResult sqrt(const ExprPtr &expression, ComputationContext &context)
ExprResult floor(const ExprPtr &expression, ComputationContext &context)
const ExprPtr & denominator
ExprResult abs(const ExprPtr &expression, ComputationContext &context)