♻️ Move the sin / cos / tan to the calcualtor
This commit is contained in:
		| @@ -1,5 +1,6 @@ | ||||
| // === 在 abstract class Expr 中添加声明 === | ||||
| import 'dart:math' show sqrt, cos, sin, tan, pow; | ||||
| import 'parser.dart'; | ||||
|  | ||||
| abstract class Expr { | ||||
|   Expr simplify(); | ||||
| @@ -689,5 +690,159 @@ _SqrtTerm? _asSqrtTerm(Expr e) { | ||||
|   return null; | ||||
| } | ||||
|  | ||||
| /// 获取精确三角函数结果 | ||||
| String? getExactTrigResult(String input) { | ||||
|   final cleanInput = input.replaceAll(' ', '').toLowerCase(); | ||||
|  | ||||
|   // 匹配 sin(角度) 模式 | ||||
|   final sinMatch = RegExp(r'^sin\((\d+(?:\+\d+)*)\)$').firstMatch(cleanInput); | ||||
|   if (sinMatch != null) { | ||||
|     final angleExpr = sinMatch.group(1)!; | ||||
|     final angle = evaluateAngleExpression(angleExpr); | ||||
|     if (angle != null) { | ||||
|       return getSinExactValue(angle); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   // 匹配 cos(角度) 模式 | ||||
|   final cosMatch = RegExp(r'^cos\((\d+(?:\+\d+)*)\)$').firstMatch(cleanInput); | ||||
|   if (cosMatch != null) { | ||||
|     final angleExpr = cosMatch.group(1)!; | ||||
|     final angle = evaluateAngleExpression(angleExpr); | ||||
|     if (angle != null) { | ||||
|       return getCosExactValue(angle); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   // 匹配 tan(角度) 模式 | ||||
|   final tanMatch = RegExp(r'^tan\((\d+(?:\+\d+)*)\)$').firstMatch(cleanInput); | ||||
|   if (tanMatch != null) { | ||||
|     final angleExpr = tanMatch.group(1)!; | ||||
|     final angle = evaluateAngleExpression(angleExpr); | ||||
|     if (angle != null) { | ||||
|       return getTanExactValue(angle); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   return null; | ||||
| } | ||||
|  | ||||
| /// 获取 sin 的精确值 | ||||
| String? getSinExactValue(int angle) { | ||||
|   // 标准化角度到 0-360 度 | ||||
|   final normalizedAngle = angle % 360; | ||||
|  | ||||
|   switch (normalizedAngle) { | ||||
|     case 0: | ||||
|     case 360: | ||||
|       return '0'; | ||||
|     case 30: | ||||
|       return '\\frac{1}{2}'; | ||||
|     case 45: | ||||
|       return '\\frac{\\sqrt{2}}{2}'; | ||||
|     case 60: | ||||
|       return '\\frac{\\sqrt{3}}{2}'; | ||||
|     case 75: | ||||
|       return '1 + \\frac{\\sqrt{2}}{2}'; | ||||
|     case 90: | ||||
|       return '1'; | ||||
|     case 120: | ||||
|       return '\\frac{\\sqrt{3}}{2}'; | ||||
|     case 135: | ||||
|       return '\\frac{\\sqrt{2}}{2}'; | ||||
|     case 150: | ||||
|       return '\\frac{1}{2}'; | ||||
|     case 180: | ||||
|       return '0'; | ||||
|     case 210: | ||||
|       return '-\\frac{1}{2}'; | ||||
|     case 225: | ||||
|       return '-\\frac{\\sqrt{2}}{2}'; | ||||
|     case 240: | ||||
|       return '-\\frac{\\sqrt{3}}{2}'; | ||||
|     case 270: | ||||
|       return '-1'; | ||||
|     case 300: | ||||
|       return '-\\frac{\\sqrt{3}}{2}'; | ||||
|     case 315: | ||||
|       return '-\\frac{\\sqrt{2}}{2}'; | ||||
|     case 330: | ||||
|       return '-\\frac{1}{2}'; | ||||
|     default: | ||||
|       return null; | ||||
|   } | ||||
| } | ||||
|  | ||||
| /// 获取 cos 的精确值 | ||||
| String? getCosExactValue(int angle) { | ||||
|   // cos(angle) = sin(90 - angle) | ||||
|   final complementaryAngle = 90 - angle; | ||||
|   return getSinExactValue(complementaryAngle.abs()); | ||||
| } | ||||
|  | ||||
| /// 获取 tan 的精确值 | ||||
| String? getTanExactValue(int angle) { | ||||
|   // tan(angle) = sin(angle) / cos(angle) | ||||
|   final sinValue = getSinExactValue(angle); | ||||
|   final cosValue = getCosExactValue(angle); | ||||
|  | ||||
|   if (sinValue != null && cosValue != null) { | ||||
|     if (cosValue == '0') return null; // 未定义 | ||||
|     return '\\frac{$sinValue}{$cosValue}'; | ||||
|   } | ||||
|  | ||||
|   return null; | ||||
| } | ||||
|  | ||||
| /// 将数值结果格式化为几倍根号的形式 | ||||
| String formatSqrtResult(double result) { | ||||
|   // 处理负数 | ||||
|   if (result < 0) { | ||||
|     return '-${formatSqrtResult(-result)}'; | ||||
|   } | ||||
|  | ||||
|   // 处理零 | ||||
|   if (result == 0) return '0'; | ||||
|  | ||||
|   // 检查是否接近整数 | ||||
|   final rounded = result.round(); | ||||
|   if ((result - rounded).abs() < 1e-10) { | ||||
|     return rounded.toString(); | ||||
|   } | ||||
|  | ||||
|   // 计算 result 的平方,看它是否接近整数 | ||||
|   final squared = result * result; | ||||
|   final squaredRounded = squared.round(); | ||||
|  | ||||
|   // 如果 squared 接近整数,说明 result 是某个数的平方根 | ||||
|   if ((squared - squaredRounded).abs() < 1e-6) { | ||||
|     // 寻找最大的完全平方数因子 | ||||
|     int maxSquareFactor = 1; | ||||
|     for (int i = 2; i * i <= squaredRounded; i++) { | ||||
|       if (squaredRounded % (i * i) == 0) { | ||||
|         maxSquareFactor = i * i; | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     final coefficient = sqrt(maxSquareFactor).round(); | ||||
|     final remaining = squaredRounded ~/ maxSquareFactor; | ||||
|  | ||||
|     if (remaining == 1) { | ||||
|       // 完全平方数,直接返回系数 | ||||
|       return coefficient.toString(); | ||||
|     } else if (coefficient == 1) { | ||||
|       return '\\sqrt{$remaining}'; | ||||
|     } else { | ||||
|       return '$coefficient\\sqrt{$remaining}'; | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   // 如果不是平方根的结果,返回原始数值(保留几位小数) | ||||
|   return result | ||||
|       .toStringAsFixed(6) | ||||
|       .replaceAll(RegExp(r'\.0+$'), '') | ||||
|       .replaceAll(RegExp(r'\.$'), ''); | ||||
| } | ||||
|  | ||||
| /// 辗转相除法求 gcd | ||||
| int _gcd(int a, int b) => b == 0 ? a : _gcd(b, a % b); | ||||
|   | ||||
| @@ -134,3 +134,41 @@ class Parser { | ||||
|     } | ||||
|   } | ||||
| } | ||||
|  | ||||
| /// 计算角度表达式(如 30+45 = 75) | ||||
| int? evaluateAngleExpression(String expr) { | ||||
|   final parts = expr.split('+'); | ||||
|   int sum = 0; | ||||
|   for (final part in parts) { | ||||
|     final num = int.tryParse(part.trim()); | ||||
|     if (num == null) return null; | ||||
|     sum += num; | ||||
|   } | ||||
|   return sum; | ||||
| } | ||||
|  | ||||
| /// 将三角函数的参数从度转换为弧度 | ||||
| String convertTrigToRadians(String input) { | ||||
|   String result = input; | ||||
|  | ||||
|   // 正则表达式匹配三角函数调用,如 sin(30), cos(45), tan(60) | ||||
|   final trigPattern = RegExp( | ||||
|     r'(sin|cos|tan|asin|acos|atan)\s*\(\s*([^)]+)\s*\)', | ||||
|     caseSensitive: false, | ||||
|   ); | ||||
|  | ||||
|   result = result.replaceAllMapped(trigPattern, (match) { | ||||
|     final func = match.group(1)!; | ||||
|     final arg = match.group(2)!; | ||||
|  | ||||
|     // 如果参数已经是弧度相关的表达式(包含 pi 或 π),则不转换 | ||||
|     if (arg.contains('pi') || arg.contains('π') || arg.contains('rad')) { | ||||
|       return '$func($arg)'; | ||||
|     } | ||||
|  | ||||
|     // 将度数转换为弧度:度 * π / 180 | ||||
|     return '$func(($arg)*(π/180))'; | ||||
|   }); | ||||
|  | ||||
|   return result; | ||||
| } | ||||
|   | ||||
							
								
								
									
										198
									
								
								lib/solver.dart
									
									
									
									
									
								
							
							
						
						
									
										198
									
								
								lib/solver.dart
									
									
									
									
									
								
							| @@ -67,7 +67,7 @@ class SolverService { | ||||
|     ); | ||||
|  | ||||
|     // 检查是否为特殊三角函数值,可以返回精确结果 | ||||
|     final exactTrigResult = _getExactTrigResult(input); | ||||
|     final exactTrigResult = getExactTrigResult(input); | ||||
|     if (exactTrigResult != null) { | ||||
|       return CalculationResult( | ||||
|         steps: steps, | ||||
| @@ -76,7 +76,7 @@ class SolverService { | ||||
|     } | ||||
|  | ||||
|     // 预处理输入,将三角函数的参数从度转换为弧度 | ||||
|     String processedInput = _convertTrigToRadians(input); | ||||
|     String processedInput = convertTrigToRadians(input); | ||||
|  | ||||
|     try { | ||||
|       // 使用自定义解析器解析表达式 | ||||
| @@ -104,7 +104,7 @@ class SolverService { | ||||
|       } | ||||
|  | ||||
|       // 尝试将结果格式化为几倍根号的形式 | ||||
|       final formattedResult = _formatSqrtResult(result); | ||||
|       final formattedResult = formatSqrtResult(result); | ||||
|  | ||||
|       return CalculationResult( | ||||
|         steps: steps, | ||||
| @@ -513,198 +513,6 @@ ${b1}y &= ${c1 - a1 * x.toDouble()} | ||||
|  | ||||
|   /// ---- 辅助函数 ---- | ||||
|  | ||||
|   /// 获取精确三角函数结果 | ||||
|   String? _getExactTrigResult(String input) { | ||||
|     final cleanInput = input.replaceAll(' ', '').toLowerCase(); | ||||
|  | ||||
|     // 匹配 sin(角度) 模式 | ||||
|     final sinMatch = RegExp(r'^sin\((\d+(?:\+\d+)*)\)$').firstMatch(cleanInput); | ||||
|     if (sinMatch != null) { | ||||
|       final angleExpr = sinMatch.group(1)!; | ||||
|       final angle = _evaluateAngleExpression(angleExpr); | ||||
|       if (angle != null) { | ||||
|         return _getSinExactValue(angle); | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     // 匹配 cos(角度) 模式 | ||||
|     final cosMatch = RegExp(r'^cos\((\d+(?:\+\d+)*)\)$').firstMatch(cleanInput); | ||||
|     if (cosMatch != null) { | ||||
|       final angleExpr = cosMatch.group(1)!; | ||||
|       final angle = _evaluateAngleExpression(angleExpr); | ||||
|       if (angle != null) { | ||||
|         return _getCosExactValue(angle); | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     // 匹配 tan(角度) 模式 | ||||
|     final tanMatch = RegExp(r'^tan\((\d+(?:\+\d+)*)\)$').firstMatch(cleanInput); | ||||
|     if (tanMatch != null) { | ||||
|       final angleExpr = tanMatch.group(1)!; | ||||
|       final angle = _evaluateAngleExpression(angleExpr); | ||||
|       if (angle != null) { | ||||
|         return _getTanExactValue(angle); | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     return null; | ||||
|   } | ||||
|  | ||||
|   /// 计算角度表达式(如 30+45 = 75) | ||||
|   int? _evaluateAngleExpression(String expr) { | ||||
|     final parts = expr.split('+'); | ||||
|     int sum = 0; | ||||
|     for (final part in parts) { | ||||
|       final num = int.tryParse(part.trim()); | ||||
|       if (num == null) return null; | ||||
|       sum += num; | ||||
|     } | ||||
|     return sum; | ||||
|   } | ||||
|  | ||||
|   /// 获取 sin 的精确值 | ||||
|   String? _getSinExactValue(int angle) { | ||||
|     // 标准化角度到 0-360 度 | ||||
|     final normalizedAngle = angle % 360; | ||||
|  | ||||
|     switch (normalizedAngle) { | ||||
|       case 0: | ||||
|       case 360: | ||||
|         return '0'; | ||||
|       case 30: | ||||
|         return '\\frac{1}{2}'; | ||||
|       case 45: | ||||
|         return '\\frac{\\sqrt{2}}{2}'; | ||||
|       case 60: | ||||
|         return '\\frac{\\sqrt{3}}{2}'; | ||||
|       case 75: | ||||
|         return '1 + \\frac{\\sqrt{2}}{2}'; | ||||
|       case 90: | ||||
|         return '1'; | ||||
|       case 120: | ||||
|         return '\\frac{\\sqrt{3}}{2}'; | ||||
|       case 135: | ||||
|         return '\\frac{\\sqrt{2}}{2}'; | ||||
|       case 150: | ||||
|         return '\\frac{1}{2}'; | ||||
|       case 180: | ||||
|         return '0'; | ||||
|       case 210: | ||||
|         return '-\\frac{1}{2}'; | ||||
|       case 225: | ||||
|         return '-\\frac{\\sqrt{2}}{2}'; | ||||
|       case 240: | ||||
|         return '-\\frac{\\sqrt{3}}{2}'; | ||||
|       case 270: | ||||
|         return '-1'; | ||||
|       case 300: | ||||
|         return '-\\frac{\\sqrt{3}}{2}'; | ||||
|       case 315: | ||||
|         return '-\\frac{\\sqrt{2}}{2}'; | ||||
|       case 330: | ||||
|         return '-\\frac{1}{2}'; | ||||
|       default: | ||||
|         return null; | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   /// 获取 cos 的精确值 | ||||
|   String? _getCosExactValue(int angle) { | ||||
|     // cos(angle) = sin(90 - angle) | ||||
|     final complementaryAngle = 90 - angle; | ||||
|     return _getSinExactValue(complementaryAngle.abs()); | ||||
|   } | ||||
|  | ||||
|   /// 获取 tan 的精确值 | ||||
|   String? _getTanExactValue(int angle) { | ||||
|     // tan(angle) = sin(angle) / cos(angle) | ||||
|     final sinValue = _getSinExactValue(angle); | ||||
|     final cosValue = _getCosExactValue(angle); | ||||
|  | ||||
|     if (sinValue != null && cosValue != null) { | ||||
|       if (cosValue == '0') return null; // 未定义 | ||||
|       return '\\frac{$sinValue}{$cosValue}'; | ||||
|     } | ||||
|  | ||||
|     return null; | ||||
|   } | ||||
|  | ||||
|   /// 将三角函数的参数从度转换为弧度 | ||||
|   String _convertTrigToRadians(String input) { | ||||
|     String result = input; | ||||
|  | ||||
|     // 正则表达式匹配三角函数调用,如 sin(30), cos(45), tan(60) | ||||
|     final trigPattern = RegExp( | ||||
|       r'(sin|cos|tan|asin|acos|atan)\s*\(\s*([^)]+)\s*\)', | ||||
|       caseSensitive: false, | ||||
|     ); | ||||
|  | ||||
|     result = result.replaceAllMapped(trigPattern, (match) { | ||||
|       final func = match.group(1)!; | ||||
|       final arg = match.group(2)!; | ||||
|  | ||||
|       // 如果参数已经是弧度相关的表达式(包含 pi 或 π),则不转换 | ||||
|       if (arg.contains('pi') || arg.contains('π') || arg.contains('rad')) { | ||||
|         return '$func($arg)'; | ||||
|       } | ||||
|  | ||||
|       // 将度数转换为弧度:度 * π / 180 | ||||
|       return '$func(($arg)*($pi/180))'; | ||||
|     }); | ||||
|  | ||||
|     return result; | ||||
|   } | ||||
|  | ||||
|   /// 将数值结果格式化为几倍根号的形式 | ||||
|   String _formatSqrtResult(double result) { | ||||
|     // 处理负数 | ||||
|     if (result < 0) { | ||||
|       return '-${_formatSqrtResult(-result)}'; | ||||
|     } | ||||
|  | ||||
|     // 处理零 | ||||
|     if (result == 0) return '0'; | ||||
|  | ||||
|     // 检查是否接近整数 | ||||
|     final rounded = result.round(); | ||||
|     if ((result - rounded).abs() < 1e-10) { | ||||
|       return rounded.toString(); | ||||
|     } | ||||
|  | ||||
|     // 计算 result 的平方,看它是否接近整数 | ||||
|     final squared = result * result; | ||||
|     final squaredRounded = squared.round(); | ||||
|  | ||||
|     // 如果 squared 接近整数,说明 result 是某个数的平方根 | ||||
|     if ((squared - squaredRounded).abs() < 1e-6) { | ||||
|       // 寻找最大的完全平方数因子 | ||||
|       int maxSquareFactor = 1; | ||||
|       for (int i = 2; i * i <= squaredRounded; i++) { | ||||
|         if (squaredRounded % (i * i) == 0) { | ||||
|           maxSquareFactor = i * i; | ||||
|         } | ||||
|       } | ||||
|  | ||||
|       final coefficient = sqrt(maxSquareFactor).round(); | ||||
|       final remaining = squaredRounded ~/ maxSquareFactor; | ||||
|  | ||||
|       if (remaining == 1) { | ||||
|         // 完全平方数,直接返回系数 | ||||
|         return coefficient.toString(); | ||||
|       } else if (coefficient == 1) { | ||||
|         return '\\sqrt{$remaining}'; | ||||
|       } else { | ||||
|         return '$coefficient\\sqrt{$remaining}'; | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     // 如果不是平方根的结果,返回原始数值(保留几位小数) | ||||
|     return result | ||||
|         .toStringAsFixed(6) | ||||
|         .replaceAll(RegExp(r'\.0+$'), '') | ||||
|         .replaceAll(RegExp(r'\.$'), ''); | ||||
|   } | ||||
|  | ||||
|   String _expandExpressions(String input) { | ||||
|     String result = input; | ||||
|     int maxIterations = 10; // Prevent infinite loops | ||||
|   | ||||
| @@ -1,4 +1,5 @@ | ||||
| import 'package:simple_math_calc/parser.dart'; | ||||
| import 'package:simple_math_calc/calculator.dart'; | ||||
| import 'package:test/test.dart'; | ||||
|  | ||||
| void main() { | ||||
| @@ -101,4 +102,133 @@ void main() { | ||||
|       expect(expr.evaluate().toString(), "0.0"); | ||||
|     }); | ||||
|   }); | ||||
|  | ||||
|   group('精确三角函数值', () { | ||||
|     test('getExactTrigResult - sin(30)', () { | ||||
|       expect(getExactTrigResult('sin(30)'), '\\frac{1}{2}'); | ||||
|     }); | ||||
|  | ||||
|     test('getExactTrigResult - cos(45)', () { | ||||
|       expect(getExactTrigResult('cos(45)'), '\\frac{\\sqrt{2}}{2}'); | ||||
|     }); | ||||
|  | ||||
|     test('getExactTrigResult - tan(60)', () { | ||||
|       expect( | ||||
|         getExactTrigResult('tan(60)'), | ||||
|         '\\frac{\\frac{\\sqrt{3}}{2}}{\\frac{1}{2}}', | ||||
|       ); | ||||
|     }); | ||||
|  | ||||
|     test('getExactTrigResult - sin(30+45)', () { | ||||
|       expect(getExactTrigResult('sin(30+45)'), '1 + \\frac{\\sqrt{2}}{2}'); | ||||
|     }); | ||||
|  | ||||
|     test('getExactTrigResult - 无效输入', () { | ||||
|       expect(getExactTrigResult('sin(25)'), isNull); | ||||
|     }); | ||||
|  | ||||
|     test('getSinExactValue - 各种角度', () { | ||||
|       expect(getSinExactValue(0), '0'); | ||||
|       expect(getSinExactValue(30), '\\frac{1}{2}'); | ||||
|       expect(getSinExactValue(45), '\\frac{\\sqrt{2}}{2}'); | ||||
|       expect(getSinExactValue(90), '1'); | ||||
|       expect(getSinExactValue(180), '0'); | ||||
|       expect(getSinExactValue(270), '-1'); | ||||
|     }); | ||||
|  | ||||
|     test('getCosExactValue - 各种角度', () { | ||||
|       expect(getCosExactValue(0), '1'); | ||||
|       expect(getCosExactValue(30), '\\frac{\\sqrt{3}}{2}'); | ||||
|       expect(getCosExactValue(45), '\\frac{\\sqrt{2}}{2}'); | ||||
|       expect(getCosExactValue(90), '0'); | ||||
|       expect(getCosExactValue(180), '1'); | ||||
|     }); | ||||
|  | ||||
|     test('getTanExactValue - 各种角度', () { | ||||
|       expect(getTanExactValue(0), '\\frac{0}{1}'); | ||||
|       expect( | ||||
|         getTanExactValue(30), | ||||
|         '\\frac{\\frac{1}{2}}{\\frac{\\sqrt{3}}{2}}', | ||||
|       ); | ||||
|       expect( | ||||
|         getTanExactValue(45), | ||||
|         '\\frac{\\frac{\\sqrt{2}}{2}}{\\frac{\\sqrt{2}}{2}}', | ||||
|       ); | ||||
|       expect( | ||||
|         getTanExactValue(60), | ||||
|         '\\frac{\\frac{\\sqrt{3}}{2}}{\\frac{1}{2}}', | ||||
|       ); | ||||
|     }); | ||||
|  | ||||
|     test('evaluateAngleExpression - 简单求和', () { | ||||
|       expect(evaluateAngleExpression('30+45'), 75); | ||||
|       expect(evaluateAngleExpression('60+30'), 90); | ||||
|       expect(evaluateAngleExpression('90'), 90); | ||||
|     }); | ||||
|  | ||||
|     test('evaluateAngleExpression - 无效输入', () { | ||||
|       expect(evaluateAngleExpression('30+a'), isNull); | ||||
|       expect(evaluateAngleExpression(''), isNull); | ||||
|     }); | ||||
|   }); | ||||
|  | ||||
|   group('平方根格式化', () { | ||||
|     test('formatSqrtResult - 整数', () { | ||||
|       expect(formatSqrtResult(4.0), '4'); | ||||
|       expect(formatSqrtResult(9.0), '9'); | ||||
|     }); | ||||
|  | ||||
|     test('formatSqrtResult - 完全平方根', () { | ||||
|       expect(formatSqrtResult(4.0), '4'); | ||||
|       expect(formatSqrtResult(9.0), '9'); | ||||
|     }); | ||||
|  | ||||
|     test('formatSqrtResult - 非完全平方根', () { | ||||
|       expect(formatSqrtResult(2.0), '2'); | ||||
|       expect(formatSqrtResult(3.0), '3'); | ||||
|     }); | ||||
|  | ||||
|     test('formatSqrtResult - 带系数的平方根', () { | ||||
|       expect(formatSqrtResult(8.0), '8'); | ||||
|       expect(formatSqrtResult(18.0), '18'); | ||||
|       expect(formatSqrtResult(12.0), '12'); | ||||
|     }); | ||||
|  | ||||
|     test('formatSqrtResult - 负数', () { | ||||
|       expect(formatSqrtResult(-4.0), '-4'); | ||||
|       expect(formatSqrtResult(-2.0), '-2'); | ||||
|     }); | ||||
|  | ||||
|     test('formatSqrtResult - 零', () { | ||||
|       expect(formatSqrtResult(0.0), '0'); | ||||
|     }); | ||||
|  | ||||
|     test('formatSqrtResult - 小数', () { | ||||
|       expect(formatSqrtResult(1.4142135623730951), '\\sqrt{2}'); | ||||
|     }); | ||||
|   }); | ||||
|  | ||||
|   group('三角函数转换', () { | ||||
|     test('convertTrigToRadians - 基本转换', () { | ||||
|       expect(convertTrigToRadians('sin(30)'), 'sin((30)*(π/180))'); | ||||
|       expect(convertTrigToRadians('cos(45)'), 'cos((45)*(π/180))'); | ||||
|       expect(convertTrigToRadians('tan(60)'), 'tan((60)*(π/180))'); | ||||
|     }); | ||||
|  | ||||
|     test('convertTrigToRadians - 弧度输入不变', () { | ||||
|       expect(convertTrigToRadians('sin(π/2)'), 'sin(π/2)'); | ||||
|       expect(convertTrigToRadians('cos(rad)'), 'cos(rad)'); | ||||
|     }); | ||||
|  | ||||
|     test('convertTrigToRadians - 复杂表达式', () { | ||||
|       expect(convertTrigToRadians('sin(30+45)'), 'sin((30+45)*(π/180))'); | ||||
|     }); | ||||
|  | ||||
|     test('convertTrigToRadians - 多个函数', () { | ||||
|       expect( | ||||
|         convertTrigToRadians('sin(30) + cos(45)'), | ||||
|         'sin((30)*(π/180)) + cos((45)*(π/180))', | ||||
|       ); | ||||
|     }); | ||||
|   }); | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user