rationalsqrt2.dart 20 KB

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