rationalsqrt2.dart 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767
  1. /* 此文件实现了有理数与二次根式形成的数域
  2. * 需要在pubspec.yaml中添加依赖rational: ^2.2.3
  3. * 使用方法请看最后的测试用例
  4. * Ksqrt类表示有理数乘以根号整数
  5. * RationalExtend类表示多个Ksqrt类根式相加
  6. * Author:nonvioce
  7. * Time: 2025.10.26
  8. */
  9. import 'package:rational/rational.dart';
  10. import 'dart:math';
  11. class Ksqrt {
  12. Rational k; // 有理数系数
  13. int q; // 底数(整数)
  14. Ksqrt(this.k, this.q) {
  15. if (q < 0) throw ArgumentError("底数q不能为负数");
  16. }
  17. // 从整数创建(系数为整数,底数为1)
  18. factory Ksqrt.fromInt(int value) {
  19. return Ksqrt(Rational.fromInt(value), 1);
  20. }
  21. // 从Rational创建(系数为有理数,底数为1)
  22. factory Ksqrt.fromRational(Rational rational) {
  23. return Ksqrt(rational, 1);
  24. }
  25. // 增强的字符串解析 - 增加小数支持
  26. factory Ksqrt.parse(String str) {
  27. str = str.trim();
  28. // 处理纯数字(整数或小数)
  29. if (RegExp(r'^-?\d+(\.\d+)?$').hasMatch(str)) {
  30. return Ksqrt.fromRational(_parseRational(str));
  31. }
  32. // 处理分数(不包含根号)
  33. if (str.contains('/') && !str.contains('√')) {
  34. try {
  35. var parts = str.split('/');
  36. if (parts.length != 2) throw FormatException("无效的分数格式: $str");
  37. var numerator = _parseRational(parts[0]);
  38. var denominator = _parseRational(parts[1]);
  39. if (denominator == Rational.zero) throw FormatException("分母不能为零: $str");
  40. return Ksqrt.fromRational(numerator / denominator);
  41. } catch (e) {
  42. throw FormatException("无效的分数格式: $str, 错误: $e");
  43. }
  44. }
  45. // 处理根式
  46. if (str.contains('√')) {
  47. var sqrtIndex = str.indexOf('√');
  48. var coefficientStr = str.substring(0, sqrtIndex);
  49. var radicandStr = str.substring(sqrtIndex + 1);
  50. // 处理括号内的底数
  51. if (radicandStr.startsWith('(') && radicandStr.endsWith(')')) {
  52. radicandStr = radicandStr.substring(1, radicandStr.length - 1);
  53. }
  54. Rational k;
  55. // 解析系数
  56. if (coefficientStr.isEmpty || coefficientStr == "+") {
  57. k = Rational.one;
  58. } else if (coefficientStr == "-") {
  59. k = -Rational.one;
  60. } else {
  61. coefficientStr = coefficientStr.replaceAll('*', '');
  62. try {
  63. if (coefficientStr.contains('/')) {
  64. var coeffParts = coefficientStr.split('/');
  65. if (coeffParts.length != 2) throw FormatException("无效的系数格式: $coefficientStr");
  66. var num = _parseRational(coeffParts[0]);
  67. var den = _parseRational(coeffParts[1]);
  68. if (den == Rational.zero) throw FormatException("分母不能为零: $coefficientStr");
  69. k = num / den;
  70. } else {
  71. k = _parseRational(coefficientStr);
  72. }
  73. } catch (e) {
  74. throw FormatException("无效的系数格式: $coefficientStr");
  75. }
  76. }
  77. // 解析底数
  78. int q;
  79. if (radicandStr.contains('/')) {
  80. throw FormatException("分数底数暂不支持: $str");
  81. } else {
  82. try {
  83. // 底数必须是整数,所以使用int.parse而不是_parseRational
  84. q = int.parse(radicandStr);
  85. } catch (e) {
  86. throw FormatException("无效的底数格式: $radicandStr");
  87. }
  88. }
  89. return Ksqrt(k, q)..simplify();
  90. }
  91. // 尝试解析为有理数(包括小数)
  92. try {
  93. return Ksqrt.fromRational(_parseRational(str));
  94. } catch (e) {
  95. throw FormatException("无法解析的字符串: $str");
  96. }
  97. }
  98. // 小数转有理数的辅助函数
  99. static Rational _parseRational(String input) {
  100. try {
  101. input = input.trim();
  102. if (input.contains('/')) {
  103. List<String> parts = input.split('/');
  104. if (parts.length == 2) {
  105. String numerator = parts[0].trim();
  106. String denominator = parts[1].trim();
  107. // 修复:直接使用 Rational 构造函数而不是 parse
  108. BigInt num = BigInt.parse(numerator);
  109. BigInt den = BigInt.parse(denominator);
  110. if (den == BigInt.zero) {
  111. throw FormatException('分母不能为零');
  112. }
  113. return Rational(num, den);
  114. }
  115. }
  116. // 处理小数
  117. if (input.contains('.')) {
  118. return _decimalToRational(input);
  119. }
  120. // 处理整数
  121. return Rational.parse(input);
  122. } catch (e) {
  123. throw FormatException('无效的分数格式: $input');
  124. }
  125. }
  126. // 小数转有理数的实现
  127. static Rational _decimalToRational(String decimalStr) {
  128. if (!decimalStr.contains('.')) {
  129. return Rational.parse(decimalStr);
  130. }
  131. List<String> parts = decimalStr.split('.');
  132. String integerPart = parts[0];
  133. String decimalPart = parts[1];
  134. // 处理负号
  135. bool isNegative = integerPart.startsWith('-');
  136. if (isNegative) {
  137. integerPart = integerPart.substring(1);
  138. }
  139. // 如果整数部分是空的,设为0
  140. if (integerPart.isEmpty) {
  141. integerPart = '0';
  142. }
  143. // 计算分母:10的decimalPart长度次方
  144. BigInt denominator = BigInt.from(10).pow(decimalPart.length);
  145. // 计算分子:整数部分 * 分母 + 小数部分
  146. BigInt numerator =
  147. BigInt.parse(integerPart) * denominator + BigInt.parse(decimalPart);
  148. if (isNegative) {
  149. numerator = -numerator;
  150. }
  151. return Rational(numerator, denominator);
  152. }
  153. // 取反运算
  154. Ksqrt operator -() {
  155. return Ksqrt(-k, q);
  156. }
  157. // 修复的化简方法
  158. void simplify() {
  159. if (k == Rational.zero) {
  160. q = 1;
  161. return;
  162. }
  163. if (q == 0 || q == 1) return;
  164. // 提取平方因子
  165. int squareFactor = 1;
  166. int temp = q;
  167. for (int i = 2; i * i <= temp; i++) {
  168. while (temp % (i * i) == 0) {
  169. squareFactor *= i;
  170. temp ~/= (i * i);
  171. }
  172. }
  173. // 更新系数和底数
  174. if (squareFactor > 1) {
  175. k *= Rational.fromInt(squareFactor);
  176. q = temp;
  177. }
  178. }
  179. // 判断两个Ksqrt是否同类项
  180. bool isLikeTerm(Ksqrt other) {
  181. Ksqrt thisCopy = Ksqrt(k, q);
  182. Ksqrt otherCopy = Ksqrt(other.k, other.q);
  183. thisCopy.simplify();
  184. otherCopy.simplify();
  185. return thisCopy.q == otherCopy.q;
  186. }
  187. // 加法运算
  188. Ksqrt operator +(Ksqrt other) {
  189. if (!isLikeTerm(other)) {
  190. throw ArgumentError("底数不同无法相加: ${this.q} 和 ${other.q}");
  191. }
  192. Ksqrt thisCopy = Ksqrt(k, q);
  193. Ksqrt otherCopy = Ksqrt(other.k, other.q);
  194. thisCopy.simplify();
  195. otherCopy.simplify();
  196. return Ksqrt(thisCopy.k + otherCopy.k, thisCopy.q);
  197. }
  198. // 减法运算
  199. Ksqrt operator -(Ksqrt other) {
  200. if (!isLikeTerm(other)) {
  201. throw ArgumentError("底数不同无法相减: ${this.q} 和 ${other.q}");
  202. }
  203. Ksqrt thisCopy = Ksqrt(k, q);
  204. Ksqrt otherCopy = Ksqrt(other.k, other.q);
  205. thisCopy.simplify();
  206. otherCopy.simplify();
  207. return Ksqrt(thisCopy.k - otherCopy.k, thisCopy.q);
  208. }
  209. // 乘法运算
  210. Ksqrt operator *(Ksqrt other) {
  211. Rational newK = k * other.k;
  212. int newQ = q * other.q;
  213. Ksqrt result = Ksqrt(newK, newQ);
  214. result.simplify();
  215. return result;
  216. }
  217. // 修复的除法运算
  218. Ksqrt operator /(Ksqrt other) {
  219. if (other.k == Rational.zero) {
  220. throw ArgumentError("除数不能为零");
  221. }
  222. // 分子分母同乘以分母的根号部分进行有理化
  223. Rational newK = k * other.k;
  224. int newQ = q * other.q;
  225. // 除以分母系数的平方(因为分母是k√q,有理化后分母变为k²q)
  226. Rational denominator = other.k * other.k * Rational.fromInt(other.q);
  227. Ksqrt result = Ksqrt(newK / denominator, newQ);
  228. result.simplify();
  229. return result;
  230. }
  231. @override
  232. bool operator ==(Object other) {
  233. if (identical(this, other)) return true;
  234. if (other is! Ksqrt) return false;
  235. Ksqrt thisSimplified = Ksqrt(k, q)..simplify();
  236. Ksqrt otherSimplified = Ksqrt(other.k, other.q)..simplify();
  237. return thisSimplified.k == otherSimplified.k &&
  238. thisSimplified.q == otherSimplified.q;
  239. }
  240. @override
  241. int get hashCode {
  242. Ksqrt simplified = Ksqrt(k, q)..simplify();
  243. return Object.hash(simplified.k, simplified.q);
  244. }
  245. // 计算表达式的近似浮点数值
  246. double toDouble() {
  247. if (k == Rational.zero) return 0.0;
  248. double sqrtQ = sqrt(q.toDouble());
  249. double kValue = k.toDouble();
  250. return kValue * sqrtQ;
  251. }
  252. @override
  253. String toString() {
  254. if (k == Rational.zero) return '0';
  255. if (q == 1) return k.toString();
  256. String kStr;
  257. if (k == Rational.one) {
  258. kStr = '';
  259. } else if (k == -Rational.one) {
  260. kStr = '-';
  261. } else {
  262. if (k.isInteger) {
  263. kStr = k.toDouble().toInt().toString();
  264. } else {
  265. kStr = '($k)';
  266. }
  267. kStr += '*';
  268. }
  269. return '${kStr}√$q';
  270. }
  271. }
  272. class RationalExtend {
  273. List<Ksqrt> terms;
  274. RationalExtend(this.terms);
  275. factory RationalExtend.fromInt(int value) {
  276. return RationalExtend([Ksqrt.fromInt(value)]);
  277. }
  278. factory RationalExtend.fromRational(Rational rational) {
  279. return RationalExtend([Ksqrt.fromRational(rational)]);
  280. }
  281. // 改进的字符串解析 - 现在支持小数
  282. factory RationalExtend.parse(String str) {
  283. str = str.replaceAll(' ', '');
  284. if (str.isEmpty) return RationalExtend([]);
  285. // 处理单个项的情况
  286. if (!str.contains('+') && !str.contains('-')) {
  287. return RationalExtend([Ksqrt.parse(str)]);
  288. }
  289. // 处理以负号开头的情况
  290. if (str.startsWith('-')) {
  291. var rest = str.substring(1);
  292. if (!rest.contains('+') && !rest.contains('-')) {
  293. return RationalExtend([Ksqrt.parse(str)]);
  294. }
  295. }
  296. List<Ksqrt> terms = [];
  297. List<String> termStrs = [];
  298. // 改进的分割逻辑:正确处理符号
  299. int start = 0;
  300. for (int i = 1; i < str.length; i++) {
  301. if ((str[i] == '+' || str[i] == '-') &&
  302. str[i-1] != '*' && str[i-1] != '/' && str[i-1] != '^') {
  303. termStrs.add(str.substring(start, i));
  304. start = i;
  305. }
  306. }
  307. termStrs.add(str.substring(start));
  308. // 解析各项
  309. for (var termStr in termStrs) {
  310. if (termStr.isEmpty) continue;
  311. if (termStr == '+') continue;
  312. try {
  313. terms.add(Ksqrt.parse(termStr));
  314. } catch (e) {
  315. throw FormatException("无法解析项: $termStr, 错误: $e");
  316. }
  317. }
  318. return RationalExtend(terms)..simplify();
  319. }
  320. void addTerm(Ksqrt term) {
  321. terms.add(term);
  322. }
  323. // 化简方法:合并同类项
  324. void simplify() {
  325. if (terms.isEmpty) return;
  326. // 首先对每个项进行化简
  327. for (var term in terms) {
  328. term.simplify();
  329. }
  330. // 合并同类项
  331. Map<int, Rational> termMap = {};
  332. for (var term in terms) {
  333. if (termMap.containsKey(term.q)) {
  334. termMap[term.q] = termMap[term.q]! + term.k;
  335. } else {
  336. termMap[term.q] = term.k;
  337. }
  338. }
  339. // 重建terms列表
  340. terms.clear();
  341. termMap.forEach((q, k) {
  342. if (k != Rational.zero) {
  343. terms.add(Ksqrt(k, q));
  344. }
  345. });
  346. // 按底数排序
  347. terms.sort((a, b) => a.q.compareTo(b.q));
  348. if (terms.isEmpty) {
  349. terms.add(Ksqrt.fromInt(0));
  350. }
  351. }
  352. // 获取共轭表达式
  353. RationalExtend get conjugate {
  354. if (terms.length == 1) {
  355. return RationalExtend([terms[0]]);
  356. } else if (terms.length == 2) {
  357. return RationalExtend([
  358. terms[0],
  359. Ksqrt(-terms[1].k, terms[1].q)
  360. ]);
  361. } else {
  362. List<Ksqrt> conjugateTerms = [terms[0]];
  363. for (int i = 1; i < terms.length; i++) {
  364. conjugateTerms.add(Ksqrt(-terms[i].k, terms[i].q));
  365. }
  366. return RationalExtend(conjugateTerms);
  367. }
  368. }
  369. // 检查是否是有理数
  370. bool get isRational {
  371. for (var term in terms) {
  372. if (term.q != 1) return false;
  373. }
  374. return true;
  375. }
  376. // 获取有理数部分的值
  377. Rational get rationalValue {
  378. if (!isRational) {
  379. throw StateError("表达式包含根号,不是纯有理数");
  380. }
  381. Rational sum = Rational.zero;
  382. for (var term in terms) {
  383. sum += term.k;
  384. }
  385. return sum;
  386. }
  387. // 加法运算
  388. RationalExtend operator +(RationalExtend other) {
  389. List<Ksqrt> newTerms = List.from(terms);
  390. newTerms.addAll(other.terms);
  391. RationalExtend result = RationalExtend(newTerms);
  392. result.simplify();
  393. return result;
  394. }
  395. // 减法运算
  396. RationalExtend operator -(RationalExtend other) {
  397. List<Ksqrt> newTerms = List.from(terms);
  398. for (var term in other.terms) {
  399. newTerms.add(Ksqrt(-term.k, term.q));
  400. }
  401. RationalExtend result = RationalExtend(newTerms);
  402. result.simplify();
  403. return result;
  404. }
  405. // 乘法运算
  406. RationalExtend operator *(RationalExtend other) {
  407. List<Ksqrt> productTerms = [];
  408. for (var term1 in terms) {
  409. for (var term2 in other.terms) {
  410. productTerms.add(term1 * term2);
  411. }
  412. }
  413. RationalExtend result = RationalExtend(productTerms);
  414. result.simplify();
  415. return result;
  416. }
  417. // 修复的除法运算
  418. RationalExtend operator /(RationalExtend other) {
  419. if (other.terms.isEmpty) {
  420. throw ArgumentError("除数不能为空");
  421. }
  422. // 特殊情况:除数是单项式
  423. if (other.terms.length == 1) {
  424. List<Ksqrt> newTerms = [];
  425. for (var term in terms) {
  426. newTerms.add(term / other.terms[0]);
  427. }
  428. return RationalExtend(newTerms)..simplify();
  429. }
  430. // 一般情况:使用分母有理化
  431. RationalExtend conjugate = other.conjugate;
  432. RationalExtend numerator = this * conjugate;
  433. RationalExtend denominator = other * conjugate;
  434. if (!denominator.isRational) {
  435. throw StateError("分母有理化失败,结果仍包含根号");
  436. }
  437. Rational denomValue = denominator.rationalValue;
  438. if (denomValue == Rational.zero) {
  439. throw ArgumentError("分母有理化后为0,无法进行除法");
  440. }
  441. // 将分子中的每一项除以分母的有理数值
  442. List<Ksqrt> resultTerms = [];
  443. for (var term in numerator.terms) {
  444. resultTerms.add(Ksqrt(term.k / denomValue, term.q));
  445. }
  446. return RationalExtend(resultTerms)..simplify();
  447. }
  448. @override
  449. bool operator ==(Object other) {
  450. if (identical(this, other)) return true;
  451. if (other is! RationalExtend) return false;
  452. RationalExtend thisSimplified = RationalExtend(List.from(terms))..simplify();
  453. RationalExtend otherSimplified = RationalExtend(List.from(other.terms))..simplify();
  454. if (thisSimplified.terms.length != otherSimplified.terms.length) return false;
  455. for (int i = 0; i < thisSimplified.terms.length; i++) {
  456. if (thisSimplified.terms[i] != otherSimplified.terms[i]) {
  457. return false;
  458. }
  459. }
  460. return true;
  461. }
  462. @override
  463. int get hashCode {
  464. RationalExtend simplified = RationalExtend(List.from(terms))..simplify();
  465. return simplified.terms.fold(0, (hash, term) => hash ^ term.hashCode);
  466. }
  467. // 计算表达式的近似浮点数值
  468. double toDouble() {
  469. double sum = 0.0;
  470. for (var term in terms) {
  471. sum += term.toDouble();
  472. }
  473. return sum;
  474. }
  475. @override
  476. String toString() {
  477. if (terms.isEmpty) return "0";
  478. RationalExtend simplified = RationalExtend(List.from(terms))..simplify();
  479. if (simplified.terms.isEmpty) return "0";
  480. List<String> termStrings = [];
  481. for (var term in simplified.terms) {
  482. String termStr = term.toString();
  483. if (termStr.startsWith('-')) {
  484. termStrings.add(termStr);
  485. } else if (termStrings.isNotEmpty) {
  486. termStrings.add('+$termStr');
  487. } else {
  488. termStrings.add(termStr);
  489. }
  490. }
  491. String result = termStrings.join('');
  492. if (result.startsWith('+')) {
  493. result = result.substring(1);
  494. }
  495. return result;
  496. }
  497. }
  498. extension RationalExtendMath on RationalExtend {
  499. RationalExtend square() {
  500. return this * this;
  501. }
  502. RationalExtend abs() {
  503. double value = this.toDouble();
  504. if (value < 0) {
  505. return RationalExtend(terms.map((term) => Ksqrt(-term.k, term.q)).toList());
  506. }
  507. return this;
  508. }
  509. bool get isZero {
  510. RationalExtend simplified = RationalExtend(List.from(terms))..simplify();
  511. return simplified.terms.length == 1 &&
  512. simplified.terms[0].k == Rational.zero;
  513. }
  514. Rational get rationalPart {
  515. Rational sum = Rational.zero;
  516. for (var term in terms) {
  517. if (term.q == 1) {
  518. sum += term.k;
  519. }
  520. }
  521. return sum;
  522. }
  523. RationalExtend get irrationalPart {
  524. List<Ksqrt> irrationalTerms = [];
  525. for (var term in terms) {
  526. if (term.q != 1) {
  527. irrationalTerms.add(term);
  528. }
  529. }
  530. return RationalExtend(irrationalTerms)..simplify();
  531. }
  532. }
  533. /*测试用例
  534. // 测试函数 - 增加小数测试
  535. void main() {
  536. print('=== Ksqrt 类测试 ===');
  537. // 基本创建和化简
  538. var sqrt8 = Ksqrt(Rational.one, 8);
  539. sqrt8.simplify();
  540. print('√8 = $sqrt8'); // 应该输出 2√2
  541. // 算术运算
  542. var a = Ksqrt.parse('√2');
  543. var b = Ksqrt.parse('3√2');
  544. var sum = a + b;
  545. print('√2 + 3√2 = $sum'); // 应该输出 4√2
  546. var product = a * b;
  547. print('√2 * 3√2 = $product'); // 应该输出 6
  548. // 除法测试 - 修复后
  549. var c = Ksqrt.parse('√6');
  550. var d = Ksqrt.parse('√3');
  551. var quotient = c / d;
  552. print('√6 / √3 = $quotient'); // 应该输出 √2
  553. print('\n=== RationalExtend 类测试 ===');
  554. // 多项式创建和运算
  555. var expr1 = RationalExtend.parse('√2 + 2√3');
  556. var expr2 = RationalExtend.parse('√2 - √3');
  557. print('表达式1: $expr1');
  558. print('表达式2: $expr2');
  559. var polySum = expr1 + expr2;
  560. print('相加: $polySum'); // 应该输出 2√2 + √3
  561. var polyProduct = expr1 * expr2;
  562. print('相乘: $polyProduct'); // 应该输出 2 + √6 - 2√3 - 2*3 = -4 + √6 - 2√3
  563. // 除法测试(分母有理化)- 修复后
  564. try {
  565. var polyQuotient = expr1 / expr2;
  566. print('相除: $polyQuotient'); // 应该输出有理化后的结果
  567. } catch (e) {
  568. print('除法错误: $e');
  569. }
  570. // 复杂表达式测试
  571. print('\n=== 复杂表达式测试 ===');
  572. try {
  573. var complexExpr = RationalExtend.parse('2/3');
  574. print('分数解析: $complexExpr');
  575. var complexExpr2 = RationalExtend.parse('2/3+√2');
  576. print('分数+根号解析: $complexExpr2');
  577. var complexExpr3 = RationalExtend.parse('1+√2');
  578. var mul = complexExpr2 * complexExpr3;
  579. print('复杂表达式1: $complexExpr2');
  580. print('复杂表达式2: $complexExpr3');
  581. print('乘积: $mul');
  582. print('有理数部分: ${complexExpr2.rationalPart}');
  583. print('无理数部分: ${complexExpr2.irrationalPart}');
  584. print('近似值: ${complexExpr2.toDouble()}');
  585. } catch (e) {
  586. print('解析错误: $e');
  587. }
  588. // 更多测试
  589. print('\n=== 更多测试 ===');
  590. try {
  591. var test1 = Ksqrt.parse('1/2');
  592. print('分数 1/2: $test1');
  593. var test2 = Ksqrt.parse('3/4*√2');
  594. print('分数系数 3/4*√2: $test2');
  595. var test3 = RationalExtend.parse('1/2 + 1/3*√2');
  596. print('混合表达式: $test3');
  597. } catch (e) {
  598. print('测试错误: $e');
  599. }
  600. // 小数测试
  601. print('\n=== 小数支持测试 ===');
  602. try {
  603. var decimal1 = Ksqrt.parse('0.5');
  604. print('小数 0.5: $decimal1');
  605. var decimal2 = Ksqrt.parse('0.25√2');
  606. print('小数系数 0.25√2: $decimal2');
  607. var decimal3 = Ksqrt.parse('1.5√3');
  608. print('小数系数 1.5√3: $decimal3');
  609. var decimal4 = RationalExtend.parse('0.5 + 3/2√2');
  610. print('混合小数表达式: $decimal4');
  611. var decimal5 = RationalExtend.parse('1/3 + 0.666√2');
  612. print('混合小数表达式: $decimal5');
  613. // 小数运算测试
  614. var decimalExpr1 = RationalExtend.parse('0.5√2');
  615. var decimalExpr2 = RationalExtend.parse('0.25√2');
  616. var decimalSum = decimalExpr1 + decimalExpr2;
  617. print('0.5√2 + 0.25√2 = $decimalSum'); // 应该输出 0.75√2
  618. var decimalProduct = decimalExpr1 * decimalExpr2;
  619. print('0.5√2 * 0.25√2 = $decimalProduct'); // 应该输出 0.25
  620. } catch (e) {
  621. print('小数测试错误: $e');
  622. }
  623. }
  624. */