
åŠçæä»£ãããåæçå°é¢æ°ãå°ãåºãã衚çŸãåçŽåããã¢ã«ãŽãªãºã ã«èå³ããããŸããã ãã®ã¿ã¹ã¯ã¯ã倧åŠã®åŸåã§é¢é£ããŠããŸããã ãã®åŸããããå®è£
ããŸãããããã¹ãŠãæå³ããæ¹æ³ã§ã¯ãããŸããã§ããïŒILã³ãŒãã®ä»£ããã«ãããã¹ã圢åŒã§CïŒã³ãŒããçæããã ãã§ãã¢ã»ã³ããªã¯ã¢ã³ããŒãããããããã«åæåœ¢åŒã§æŽŸçç©ãå°åºããæ¹æ³ã¯ãããŸããã§ãã ããããé¢å¿ãæ®ã£ãããããã®ãããªã©ã€ãã©ãªãå®è£
ããããšã«ããŸããã ã€ã³ã¿ãŒãããäžã«ãã®ãããªã©ã€ãã©ãªã倿°ããããšã¯æ³šç®ã«å€ããŸãããILã³ãŒãã«åŒãã³ã³ãã€ã«ããæ®µéãã€ãŸã å®éãã³ã³ãã€ã«ãšã¯ç°ãªããããã»ã©å¹æçã§ã¯ãªãè§£éãã©ãã§ãå®è¡ãããŸãã ããã«ãç¹ã«ãèªåã®ä»äºã®çµæãã©ããã§å¿
èŠã«ãªãããšãç¹ã«æãã§ããªãã®ã«ãæ°ããæè¡ãç ç©¶ããããã«ãç§èªèº«ã®ããã«ãããéçºããŸããã ãã£ãã¡ãªäººïŒ
ãœãŒã¹ã³ãŒã ã
ããã°ã©ã ã
äœ¿çšæžã¿ã®ããã°ã©ã ãšã©ã€ãã©ãª
- GOLD Parsing System-ææ³ãèšè¿°ããããŸããŸãªèšèªïŒCãCïŒãJavaãJavaScriptãObjective-CãPerlãPythonãRubyãªã©ïŒã®ã¬ã¯ãµãŒãšããŒãµãŒã®ã³ãŒããçæããIDEã LALRè§£æã«åºã¥ããŠããŸãã
- Visual Studio 2010
- GOLD.Engine-çæãããããŒãã«ãšå¯Ÿè©±ããããã«æ¥ç¶ããã.NETã®ã¢ã»ã³ããªã
- NUnit-.NETçšã®ãªãŒãã³ãœãŒã¹ã®åäœãã¹ãç°å¢ã
- ILSpy-.NETçšã®ãªãŒãã³ãœãŒã¹éã¢ã»ã³ãã©ãŒ ã
ããã»ã¹å
šäœãå£ããæ®µéïŒ
- åŒããªãŒã®æ§ç¯
- åæå°é¢æ°ã®èšç®
- åŒã®ç°¡ç¥å
- åççãªåæ°åŠç
- åŒã®ã³ã³ãã€ã«
åŒããªãŒã®æ§ç¯
GANTããŒãµãŒãžã§ãã¬ãŒã¿ãŒãéžæããŸãããANTLRã®çµéšããããæ°ãããã®ã欲ããã£ãããã§ãã ãŸãããã®å©ç¹ã¯ãä»ãšæ¯èŒããŠ
ããã®è¡šã§èŠãããšãã§ã
ãŸã ã ã芧ã®ãšãããANTLRãšæ¯èŒãããšãGOLDã¯
LLã§ã¯ãªã
LALRã¢ã«ãŽãªãºã ã«åºã¥ããŠããŸãã ããã¯ãçè«çã«ã¯ãçæãããããŒãµãŒã¯ããé«éã§åŒ·åã§ãããäžæ¹ã§ãããã°ã§ããªãããšãæå³ããŸãïŒGOLDã§ã¯ããã¡ã€ã«ã¯ãã€ããªåœ¢åŒã§ããŠã³ããŒããããŸãïŒãå¯èœã§ããã°ãå®å
šã«äžæçã§äžäŸ¿ã§ãã ãã1ã€ã®å€§ããªéãã¯ãææ³åœ¢åŒïŒ
EBNFã§ã¯ãªã
BNFã§ãã ããã¯ããã®åœ¢åŒã§æžãããææ³ã¯ãå±±æ¬åŒ§ãå®çŸ©ã®èšå·ãæ¡ä»¶ä»ãã®åºçŸãšç¹°ãè¿ãã®æ¬ åŠã®ããã«ãããã«å€§ãããµã€ãºãæã€ããšãæå³ã
ãŸã ïŒ
wikiã«ãã
ãŸã ããŸããäŸãã°ãEBNFã®ãããªã«ãŒã«
ExpressionList = Expression { ',' Expression }
次ã®åœ¢åŒã§æžãæããããŸãã
<ExpressionList> ::= <ExpressionList> ',' <Expression> | <Expression>
ãããã£ãŠãæ°åŒã®æçµçãªææ³ã¯æ¬¡ã®åœ¢åŒã«ãªããŸãã
æ°åŒã®ææ³ "Name" = 'Mathematics expressions' "Author" = 'Ivan Kochurkin' "Version" = '1.0' "About" = '' "Case Sensitive" = False "Start Symbol" = <Statements> Id = {Letter}{AlphaNumeric}* Number1 = {Digit}+('.'{Digit}*('('{Digit}*')')?)? Number2 = '.'{Digit}*('('{Digit}*')')? AddLiteral = '+' | '-' MultLiteral = '*' | '/' <Statements> ::= <Statements> <Devider> <Statement> | <Statements> <Devider> | <Statement> <Devider> ::= ';' | '.' <Statement> ::= <Expression> '=' <Expression> | <Expression> <Expression> ::= <FuncDef> | <Addition> <FuncDef> ::= Id '(' <ExpressionList> ')' | Id '' '(' <ExpressionList> ')' | Id '(' <ExpressionList> ')' '' <ExpressionList> ::= <ExpressionList> ',' <Expression> | <Expression> <Addition> ::= <Addition> AddLiteral <Multiplication> | <Addition> AddLiteral <FuncDef> | <FuncDef> AddLiteral <Multiplication> | <FuncDef> AddLiteral <FuncDef> | <Multiplication> <Multiplication> ::= <Multiplication> MultLiteral <Exponentiation> | <Multiplication> MultLiteral <FuncDef> | <FuncDef> MultLiteral <Exponentiation> | <FuncDef> MultLiteral <FuncDef> | <Exponentiation> <Exponentiation> ::= <Exponentiation> '^' <Negation> | <Exponentiation> '^' <FuncDef> | <FuncDef> '^' <Negation> | <FuncDef> '^' <FuncDef> | <Negation> <Negation> ::= AddLiteral <Value> | AddLiteral <FuncDef> | <Value> <Value> ::= Id | Number1 | Number2 | '(' <Expression> ')' | '|' <Expression> '|' | '(' <Expression> ')' '' | '|' <Expression> '|' '' | Id ''
ããŒã¯ã³ãé€ããŠãææ³ã§ã¯ãã¹ãŠãæãããªããã§ãïŒ
Number1 = {Digit} +ïŒ 'ã' {Digit} *ïŒ 'ïŒ' {Digit} * 'ïŒ'ïŒïŒïŒïŒ ãã®èšèšã«ãããæ¬¡ã®åœ¢åŒã®è¡ãè§£æã§ããŸãã0.1234ïŒ56ïŒãããã¯ãåççãªå°æ°éšãæå³ããïŒ61111/495000 ãã®ãããªæååãåæ°ã«å€æããæ¹æ³ã«ã€ããŠã¯ãåŸã§èª¬æããŸãã
ãããã£ãŠãã³ã³ãã€ã«æžã¿ã®ææ³ããŒãã«ïŒã³ã³ãã€ã«æžã¿ææ³ããŒãã«ãã¡ã€ã«ïŒãçæãããããŒãµãŒã¯ã©ã¹ãã¬ãŒã ã¯ãŒã¯ãäœæãããåŸãé©åãªASTããªãŒãæ§ç¯ããããã«åŸè
ã倿Žããå¿
èŠããããŸãã ãã®å Žåã®ããŒãµãŒã¯ã©ã¹ãã¬ãŒã ã¯ãŒã¯ã¯ããã¹ãŠã®ææ³ã«ãŒã«ã®ã«ãŒããããŒã¯ã³ã®äžæ£ãªã·ãŒã±ã³ã¹ããã®ä»ã®ãšã©ãŒã®å Žåã®äŸå€åŠçãå«ã.csãã¡ã€ã«ã§ãïŒã¡ãªã¿ã«ãGOLDã«ã¯ãã®ãããªãã¬ãŒã ã¯ãŒã¯ã®ç°ãªããžã§ãã¬ãŒã¿ãŒããããCook .NETãéžæããŸããïŒ ãããã£ãŠããã®å Žåããé©åãªããšã¯ã次ã®ã¿ã€ããæã€ããšãã§ããããŒãã§æ§æãããããªãŒãæå³ããŸãã
- èšç®æžã¿ -ã³ã³ãã€ã©ãŒãåãå
¥ãå¯èœãªäºé圢åŒã§èšç®ããã宿°ã衚ãããŒããããšãã°ãã0.714285714285714ããã0.12222222222222222ãã ããããåãã§ãã£ãŠãããã®ãããªå®æ°ããšã«æ°ãããªããžã§ã¯ããäœæãããŸãã
- å€ -èšç®ããã宿°ãæçæ°ã®åœ¢åŒã§è¡šãããŒããã€ãŸã 1ã¯ã1/1ããã0.1ïŒ2ïŒãã¯ã11/90ããã0.1234ãã¯ã617/5000ããšããŠè¡šãããŸãã ããããåãã§ãã£ãŠãããã®ãããªå®æ°ããšã«æ°ãããªããžã§ã¯ããäœæãããŸãã
- 宿° -æªå®çŸ©ã®å®æ°ã衚ãããŒããããšãã°ãaãããbããªã©ã2ã€ã®å®æ°ãåŒã§èŠã€ãã£ãå Žåããããã¯1ã€ã®ããŒããæããŸãã
- 倿° - 倿°ã衚ãããŒããããšãã°ãxãããyããªã©ãç¹å®ã®å€æ°ãåŒã§è€æ°ååºçŸããå Žåããã®å€æ°ãšæªå®çŸ©ã®å®æ°ã«å¯ŸããŠ1ã€ã®ãªããžã§ã¯ãã®ã¿ãäœæãããŸãã 宿°ãšå€æ°ã®åºå¥ã¯ãåæå°é¢æ°ã®å°åºã®æ®µéã§ã®ã¿éèŠã§ãããä»ã®å Žåããã®ç¥èã¯å¿
èŠãªãããšãçè§£ããããšãéèŠã§ãã
- 颿° - 颿°ã衚ãããŒããããšãã°ãã+ãããsinããã^ããªã©ã åãæã€ããšãã§ããå¯äžã®ããŒãã
å³ã«ã¯ããã¹ãŠã®ã¿ã€ãã®ããŒããæç¢ºã«ç€ºãããŠããŸãã

ææ³ãããçµæã®ããªãŒã®ããŒãã«ã¯åïŒå€ã倿°ãªã©ïŒããªãããæšæºé¢æ°ïŒcosãå ç®ãã¹ãä¹ãªã©ïŒã®å Žåã¯1ã2åã®åãããããšãããããŸãã ä»ã®ãã¹ãŠã®é¢æ°ã«ã¯ããã«åŒæ°ããããŸãããèæ
®ãããŸããã§ããã
ãããã£ãŠããã¹ãŠã®ããŒãïŒãŸãã¯æ©èœãæã€ããŒãïŒã«ã¯ã0ã2åã®åãå«ãŸããŸãã ããã¯çè«çãªèгç¹ããåœãŠã¯ãŸããŸãã ããããå®éã«ã¯ãã+ãããã³ã*ã颿°ã®åã®æ°ãç¡å¶éã«ããåŸã§æ€èšããåçŽåã®ã¿ã¹ã¯ã容æã«ããå¿
èŠããããŸããã ã¡ãªã¿ã«ãã-ããã/ããªã©ã®ãã€ããªæŒç®ãåãçç±ã§ç Žæ£ããå¿
èŠããããŸããïŒå³åŽã®åŠå®ã«ããå ç®ãšå³åŽã®å転ã«ããä¹ç®ã«çœ®ãæããããŸããïŒã
ãã®ãããè§£ææ®µéã§ãåã«ãŒã«ã®ãã¹ãŠã®ããŒããèœã¡ããã
Nodesãšãããããã¡ãŒããååŸãããŸãã ãããã£ãŠãããã»ã¹å
šäœã®æåŸã«ãå³åŽãšå·ŠåŽã®éšåãæã€1ã€ä»¥äžã®é¢æ°ããã®ãããã¡ãŒã«æ®ããŸãã ãŸããæ§æè§£æã®éçšã§ãå ç®é¢æ°ãšä¹ç®é¢æ°ãå€åœèªã§ããã«äœæãããããã«ã颿°ã®çŸåšã®åŒæ°ã®æ°ãšçŸåšã®é¢æ°ã®åãããããæ ŒçŽãã远å ã®ãããã¡ãŒArgsCountãšArgsFuncTypesã䜿çšãããŸããã ãããã£ãŠãããšãã°ãä¹ç®é¢æ°ã®å Žåãæ¬¡ã®ã³ãŒãã䜿çšãããŸãã
æåã®ä¹æ°ã®åŠçïŒ
içªç®ã®ä¹æ°ã®åŠçïŒ
æåŸã®ä¹æ°ã®åŠçïŒ
ãã®ã³ãŒãã¯ãããšãã°ãä¹ç®ããªãå Žåã
PushOrRemoveFuncã䜿çšããŠèŠçŽ ããŒãã®æåŸã®ä¹ç®é¢æ°ãåé€ããå¿
èŠãããããšã
瀺ããŠããŸãã 远å ããã«ã¯ãåæ§ã®ã¢ã¯ã·ã§ã³ãå®è¡ããå¿
èŠããããŸãã
åäžã®åŒæ°ã®é¢æ°ããã€ããªé¢æ°ã宿°ã倿°ãå€ã®åŠçã¯ç°¡åã§ããã
MathExprParser.csã§
ããããã¹ãŠã確èªã§ããŸãã
åæå°é¢æ°ã®èšç®
ãã®æ®µéã§ã颿°ããã®å°é¢æ°ã«å€æããå¿
èŠããããŸãã
æåã®æ®µéãããããããã«ãäœæãããåŒããªãŒã«ã¯4ã€ã®ã¿ã€ãã®ããŒããããããŸããïŒ5çªç®ã®ããŒãã¯åŸã§è¡šç€ºãããŸãïŒã ãããã«ã€ããŠãå°é¢æ°ãå®çŸ©ããŸãã
- å€ '= 0
- 宿° '= 0
- 倿° '= 1
- 颿° '=èªå°äœ[颿°]
説æããŠã¿ãŸãããïŒå°é¢æ°ã«ã€ããŠã¯ãäºåã«æºåããã衚圢åŒã®å€ãååŸããå¿
èŠãããããã®å€ã«ã¯å°é¢æ°ããããããç¹å®ã®å°é£ãçããŸãã ããã»ã¹ã¯æ¬è³ªçã«ååž°çã§ãã ãã®ãããªå®è£
ããã眮æã®å®å
šãªãªã¹ãã¯ã以äžã®ãã¿ãã¬ã®äžã«ãããŸãã
ããªããã£ãã®ãªã¹ã (f(x) ^ g(x))' = f(x) ^ g(x) * (f(x)' * g(x) / f(x) + g(x)' * ln(f(x)));"); neg(f(x))' = neg(f(x)');"); sin(f(x))' = cos(f(x)) * f(x)'; cos(f(x))' = -sin(f(x)) * f(x)'; tan(f(x))' = f(x)' / cos(f(x)) ^ 2; cot(f(x))' = -f(x)' / sin(f(x)) ^ 2; arcsin(f(x))' = f(x)' / sqrt(1 - f(x) ^ 2); arccos(f(x))' = -f(x)' / sqrt(1 - f(x) ^ 2); arctan(f(x))' = f(x)' / (1 + f(x) ^ 2); arccot(f(x))' = -f(x)' / (1 + f(x) ^ 2); sinh(f(x))' = f(x)' * cosh(x); cosh(f(x))' = f(x)' * sinh(x); arcsinh(f(x))' = f(x)' / sqrt(f(x) ^ 2 + 1); arcosh(f(x))' = f(x)' / sqrt(f(x) ^ 2 - 1); ln(f(x))' = f(x)' / f(x); log(f(x), g(x))' = g'(x)/(g(x)*ln(f(x))) - (f'(x)*ln(g(x)))/(f(x)*ln(f(x))^2);
ãã¹ãŠã®æŽŸçç©ãã³ãŒãå
ã§ããŒãã«èšè¿°ãããŠããããã§ã¯ãªããåçã«å
¥åããã³è§£æããããšãã§ããŸãã
äžèšã®ããã«ããããã¯ããã€ãã®åŒæ°ãæã€é¢æ°ã§ããããããã®ãªã¹ãã«ã¯å ç®ãŸãã¯ä¹ç®ã¯ãããŸããã ãããŠããã®ãããªã«ãŒã«ãè§£æããã«ã¯ãå€ãã®ã³ãŒããæžãå¿
èŠããããŸãã åãçç±ã§ãæ©èœã®æ§æã¯ãããŸããã ïŒfïŒgïŒxïŒïŒïŒ '= fïŒgïŒxïŒïŒ' * gïŒxïŒ 'ã®ä»£ããã«ããã¹ãŠã®é¢æ°ã¯é¢æ°ã®æ§æãšããŠè¡šãããŸãã
ãŸããDerivativesã®é¢æ°ïŒã€ãŸããæªå®çŸ©ã®é¢æ°ïŒã®çœ®æãèŠã€ãããªãã£ãå Žåãããã¯åã«ã¹ãããŒã¯ã®ãã颿°ã«çœ®ãæããããŸãã fïŒxïŒã¯fïŒxïŒ 'ã«ãªããŸãã
åæå°é¢æ°ãæ£åžžã«ååŸãããåŸãçµæã®åŒã«ã¯ãa + 0ãa * 1ãa * a ^ -1ãªã©ãå€ãã®ãã¬ããŒãžãããããšããåé¡ãçºçããŸãããŸããçµæã®åŒã¯ããæé©ãªæ¹æ³ã§èšç®ã§ããŸãã ããšãã°ãåçŽãªåŒã§ãã£ãŠããèŠèŠããåŒã«ãªããŸãã
(x^2 + 2)' = 0 + 2 * 1 * x ^ 1
åçŽåã¯ããã®ãããªæ¬ ç¹ã«å¯ŸåŠããããã«äœ¿çšãããŸãã
åŒã®ç°¡ç¥å
ãã®æ®µéã§ã¯ãå°é¢æ°ãèšç®ããæ®µéãšã¯ç°ãªããåçŽãªèŠåãå¥ã®å Žæã«æžãçããŸããã§ãããå ç®ãšä¹ç®ã®é¢æ°ã¯ããã€ãã®åŒæ°ã®é¢æ°ã§ããããããã®ãããªèŠåãäœæããã®ã¯ããçšåºŠå°é£ã§ãå埩èšèªã®ã³ã³ããã¹ãã
ãããã¯ã®åé ã§ãå ç®ãšä¹ç®ãné
颿°ãšããŠè¡šãããçç±ã®ãããã¯ã«è§ŠããŸããã äžã®åçã«ç€ºãããŠããç¶æ³ãæ³åããŠãã ããã ããã§
ãaãš
-aãçç¥ãããŠ
ããããšãããããŸãã ãããããã€ããªé¢æ°ã®å Žåã«ãããè¡ãæ¹æ³ã¯ïŒ ãããè¡ãã«ã¯ãããŒã
a ã
bãããã³
cãå埩åŠçããŠã
aããã³
-aãåãããŒãã®åã§ããããšãåŸã§çºèŠããŸããããã¯ãããŒããšãšãã«ããŒããåæžã§ããããšãæå³ããŸãã ãã ããå³ã®å³ã«ç€ºãããã«ãããªãŒããœãŒãããããšã¯ãåçŽãªã¿ã¹ã¯ã§ã¯ãããŸããããã¹ãŠã®åãäžåºŠã«ãã¹ãŠã®ã¢ã¯ã·ã§ã³ãäžåºŠã«å®è¡ããæ¹ãã¯ããã«ç°¡åã ããã§ãã ãšããã§ããã®ãããªåæåã«ããã
çµåæ§ãš
坿æ§ã®æ°åŠçç¹æ§ãäœæã§ããŸãã
åçŽåããã»ã¹äžã«ã2ã€ã®ããŒããæ¯èŒãããšããåé¡ãçºçããŸãã2ã€ã®ããŒãã¯ã4ã€ã®ã¿ã€ãã®ããããã«ãªããŸãã ããã¯ãããšãã°ãsinïŒx + yïŒã-sinïŒx + yïŒãªã©ã®åŒãæžããããã«å¿
èŠã§ãã ããŒãããšã«ããŒãèªäœãšãã®ãã¹ãŠã®åå«ãæ¯èŒã§ããããšã¯æããã§ãã ããããåé¡ã¯ããã®æ¹æ³ã§ã¯ãããšãã°sinïŒx + yïŒã-sinïŒy + xïŒã®ããã«ãçšèªãå åãåé
眮ãããç¶æ³ã«å¯ŸåŠã§ããªãããšã§ãã ãã®åé¡ã解決ããããã«ã坿æ§ã®ç¹æ§ãæºããããçšèªãŸãã¯å åã®äºåçãªãœãŒãã䜿çšãããŸãïŒã€ãŸããå ç®ãšæžç®ïŒã ããŒãã¯ã次ã®å³ã«ç€ºãããã«æ¯èŒãããŸãã å€ã¯å®æ°ããå°ããã宿°ã¯å€æ°ããå°ããããªã©ã 颿°ã®å Žåãååã ãã§ãªãåŒæ°ã®æ°ãšåŒæ°èªäœãæ¯èŒããå¿
èŠãããããããã¹ãŠãå°ãè€éã«ãªããŸãã

ãããã£ãŠãäžèšã®ãã¹ãŠã®å€æãšåæã®åŸãå
ã®åŒã¯éåžžã«åçŽåãããŸãã
åççãªåæ°åŠç
ç§ãèŠã€ããåççãªå®è£
ã§ã¯ãéåžžã®æåååãããšãã°0.666666ã¯ãç¹å®ã®ååãšåæ¯ãæã€åæ°åã«å€æãããŸããã§ããã äžå®ã®ç²ŸåºŠã§2/3ã§ã 次ã«ãå€ãã®ãªãã·ã§ã³ã䜿çšããŠå®è£
ãäœæããããšã«ããŸããã 以äžã®é¢æ°ã¯ãããšãã°ãç¹å®ã®æ°ãçŽç²ã«éåççã§ãããããããåšæãŸãã¯æéå°æ°éšãæã¡ãåççãªãã®ãããšãã°äžå®ã®ç²ŸåºŠã§sinïŒpiïŒãã0ã«å€æã§ããããæ±ºå®ã§ããŸãã äžè¬çã«ã
stackoverflow.comãžã®ç§ã®åçã®ãã®ä»ã®è©³çްãåç
§
ããŠãã ããã ã¡ãœããã®ç°¡åãªã°ã©ãã£ã«ã«ãªèª¬æãäžã®å³ã«ç€ºããã³ãŒããäžã®ãªã¹ãã«ç€ºããŸãã ããã«ãããããããæšæºçãªæ°åŠé¢æ°ãš
doubleåã®ç²ŸåºŠã¯ãæçæ°ãšå®æ°ã®éåžžã®èªèã«ã¯ååã§ã¯ãããŸããããçè«çã«ã¯ãã¹ãŠãæ©èœããããšã«æ³šæããŠãã ããã

åŒã®ã³ã³ãã€ã«
åçŽå段éã®åŸãçµæã®ã»ãã³ãã£ãã¯ããªãŒãILã³ãŒãã«å€æããããã«ãMono.Cecilã䜿çšããŸããã
ããã»ã¹ã®éå§æã«ãã³ãã³ããèšè¿°ãããã¢ã»ã³ããªãã¯ã©ã¹ãããã³ã¡ãœãããäœæãããŸãã æ¬¡ã«ãåFuncNodeã«ã€ããŠãããã°ã©ã ã«è¡šç€ºãããåæ°ãèšç®ãããŸãã ããšãã°ã颿°
sinïŒx ^ 2ïŒ* cosïŒx ^ 2ïŒãããå Žåããã®äžã«xã2ã®ã¹ãä¹ãã颿°ã2åçºçãã颿°sinãšcosãäžåºŠã«1ã€ãã€çºçããŸãã å°æ¥ã颿°èšç®ã®ç¹°ãè¿ãã«é¢ãããã®æ
å ±ã¯ã次ã®ããã«äœ¿çšãããŸãïŒã€ãŸãããã®æ¹æ³ã§ã¯ã2çªç®ã®é¢æ°ã¯åã颿°ã2åèšç®ããŸããïŒã
if (!func.Calculated) { EmitFunc(funcNode); func.Calculated = true; } else IlInstructions.Add(new OpCodeArg(OpCodes.Ldloc, funcNode.Number));
ãã®ãã¹ãŠã®ã³ãŒããçæããåŸãäžã®å³ã«ç€ºãããã«ãILã³ãŒãã®ä»ã®æé©åãå¯èœã§ãã

ãã®åçã§ã¯ïŒ
- Ldarg-ç¹å®ã®é¢æ°åŒæ°ãã¹ã¿ãã¯ã«ããŒãããæäœã
- Ldc_R8-ç¹å®ã®doubleå€ãã¹ã¿ãã¯ã«ããŒãããŸãã
- Stloc.n-ã¹ã¿ãã¯ããæåŸã®å€ãååŸããããŒã«ã«å€æ°nã«ä¿åããŸãã
- Ldloc.n-ããŒã«ã«å€æ°n ãã¹ã¿ãã¯ã«ããã·ã¥ããŸãã
ç¹å®ã®æ¡ä»¶ãæºããããå ŽåãããŒãžã¥è²ã®ããã¯ã¹å
ã®æç€ºãåé€ã§ããŸãã ããšãã°ãå·Šäžã®ç»åã®å Žåã¯æ¬¡ã®ããã«èª¬æãããŸãïŒçŸåšã®åœä»€ã颿°ããåŒæ°ãèªã¿èŸŒãã§ãããã宿°ãèªã¿èŸŒãã§ãããæ¬¡ã®åœä»€ããããããŒã«ã«å€æ°
nã«ä¿åããŠããå ŽåãããŒã«ã«å€æ°
nã®èªã¿èŸŒã¿åœä»€ãèªã¿èŸŒã¿ã§çœ®ãæããããšã«ããããã®åœä»€ã®ãããã¯ãåé€ã§ããŸã颿°ã®åŒæ°ãŸãã¯å®æ°ã®èªã¿èŸŒã¿ã ããŒã«ã«å€æ°
nã®æåã®saveã¹ããŒãã¡ã³ããŸã§çœ®æããã»ã¹ãç¶ããŸãã ä»ã®3ã€ã®ã±ãŒã¹ãåæ§ã«èª¬æãããŠããŸãã ããšãã°ãã·ãŒã±ã³ã¹
Ldloc.n ;
Stloc.nã¯ããã«åé€ã§ããŸãã
ãããã®æé©åã¯ãã³ãŒãã«åå²ããªãå Žåã«ãé©çšã§ããããšã«æ³šæãã䟡å€ããããŸããããã¯æããã§ãïŒå®å
šã«æããã§ãªãå Žåã¯ãèããŠã¿ãããšããå§ãããŸãïŒã ããããç§ã®å Žåãæ°åŠé¢æ°ãšãã®å°é¢æ°ã®ã³ãŒãã«ã¯ãµã€ã¯ã«ãå«ããããšãã§ããªããããããã¯ãã¹ãŠæ©èœããŸãã
é«éã¹ãä¹
ç§ã¯ãã»ãšãã©èª°ãã
ãåãçŽ æ©ãåã«äžããããã®
ã¢ã«ãŽãªãºã ã«ã€ããŠç¥ã£ãŠãããšæããŸãã ãã ãã以äžã®ã¢ã«ãŽãªãºã ã¯ã³ã³ãã€ã«ã¬ãã«ã§è¡šç€ºãããŸãã
ILã³ãŒãã«å®è£
ãããé«éã¹ãä¹ã¢ã«ãŽãªãºã if (power <= 3) { IlInstructions.Add(new OpCodeArg(OpCodes.Stloc, funcNode.Number)); IlInstructions.Add(new OpCodeArg(OpCodes.Ldloc, funcNode.Number)); for (int i = 1; i < power; i++) { IlInstructions.Add(new OpCodeArg(OpCodes.Ldloc, funcNode.Number)); IlInstructions.Add(new OpCodeArg(OpCodes.Mul)); } } else if (power == 4) { IlInstructions.Add(new OpCodeArg(OpCodes.Stloc, funcNode.Number)); IlInstructions.Add(new OpCodeArg(OpCodes.Ldloc, funcNode.Number)); IlInstructions.Add(new OpCodeArg(OpCodes.Ldloc, funcNode.Number)); IlInstructions.Add(new OpCodeArg(OpCodes.Mul)); IlInstructions.Add(new OpCodeArg(OpCodes.Stloc, funcNode.Number)); IlInstructions.Add(new OpCodeArg(OpCodes.Ldloc, funcNode.Number)); IlInstructions.Add(new OpCodeArg(OpCodes.Ldloc, funcNode.Number)); IlInstructions.Add(new OpCodeArg(OpCodes.Mul)); } else {
é«é环ä¹ã¢ã«ãŽãªãºã ã¯æé©ãªçޝä¹ã¢ã«ãŽãªãºã ã§ã¯ãªãããšã«æ³šæããŠãã ããã ããšãã°ã次ã®2ã€ã®æ¹æ³ã§åã倿°ã5åä¹ç®ããŸãã x ^ 4 + x ^ 3 + x ^ 2 + x = x *ïŒx *ïŒx *ïŒx + 1ïŒ+ 1ïŒ+ 1ïŒãªã©ã®æé©åãå®è£
ãããŠããŸããã
- var t = a ^ 2; a * a * a * a * a * a * a = t ^ 2 * t-éåžžã®ãé«éãã¢ã«ãŽãªãºã ã
- a * a * a * a * a * a * a =ïŒa ^ 3ïŒ^ 2-æé©ãªãé«éãã¢ã«ãŽãªãºã ã
ãšããã§ãéåžžã®åºå®æ°doubleã®å Žåãäžèšã®ä¹ç®ã®ç°ãªãé åºã§ã®ä¹ç®ã®çµæã¯ç°ãªãããšã«æ³šæããŠãã ããïŒã€ãŸãïŒa ^ 2ïŒ^ 2 * a ^ 2ïŒ=ïŒA ^ 3ïŒ^ 2 ïŒ ãã®ãããäžéšã®ã³ã³ãã€ã©ã¯ãããã®åŒã®å€ããæé©åããŸããã stackoverlofwã«ã¯ããã«é¢ããè峿·±ãQïŒAããããŸãã
ãªãGCCã¯a * a * a * a * a * aãïŒa * a * aïŒ*ïŒa * a * aïŒã«æé©åããªãã®ã§ããïŒ ãããŠã
ãªãMath.PowïŒxã2ïŒã¯x * xã³ã³ãã€ã©ãŒã«ãJITã«ãæé©åãããŠããªãã®ã§ãã ã
ããŒã«ã«å€æ°ã®æé©å
åã®æé ãããããããã«ãããŒã«ã«å€æ°ã¯ãå
ã®åŒã§è€æ°åçºçãããã¹ãŠã®é¢æ°ã®çµæãæ ŒçŽããããã«äœ¿çšãããŸãã ããŒã«ã«å€æ°ãæäœããã«ã¯ã2ã€ã®åçŽãªåœä»€
stlocãš
ldlocã®ã¿ã䜿çšãããŸãããããã¯ããã®ããŒã«ã«å€æ°ã®æ°ãæ
åœãã1ã€ã®åŒæ°ã䜿çšããŸãã ãã ããããŒã«ã«å€æ°ã®æ°ããèšç®çµæãç¹°ãè¿ã衚瀺ããããã³ã«ïŒäœæããããã«ïŒã€ã³ã¯ãªã¡ã³ããããå ŽåãããŒã«ã«å€æ°ã倿°ååšããå¯èœæ§ããããŸãã ãã®åé¡ã軜æžããããã«ãããŒã«ã«å€æ°ã®ã©ã€ããµã€ã¯ã«ãå§çž®ããã¢ã«ãŽãªãºã ãå®è£
ãããŸããããã®ããã»ã¹ã¯äžã®å³ã«æç¢ºã«ç€ºãããŠããŸãã ã芧ã®ãšãããåŒã§ã¯5ã€ã®ããŒã«ã«å€æ°ã®ä»£ããã«3ã€ãã䜿çšã§ããŸããããã ãããã®ã貪欲ãªãã¢ã«ãŽãªãºã ã¯æé©ãªé åã§ã¯ãããŸããããå®è£
ããã¿ã¹ã¯ã«ã¯éåžžã«é©ããŠããŸãã
æªå®çŸ©ã®é¢æ°ãšãã®æŽŸçç©ã®ã³ã³ãã€ã«
éçºããã©ã€ãã©ãªã§ã¯ãfïŒxïŒãšãã圢åŒã®1ã€ã®å€æ°ã®åçŽãªé¢æ°ã ãã§ãªããfïŒxãaãbïŒxïŒïŒãªã©ã®ä»ã®å€æ°ã䜿çšã§ããŸããããã§ãaã¯æªç¥ã®å®æ°ã§ãbïŒxïŒã¯æªç¥ã®é¢æ°ã§ãããªã²ãŒããšããŠéä¿¡ãããŸãã ãåç¥ã®ããã«ã颿°ã®å°é¢æ°ã®å®çŸ©ã¯æ¬¡ã®ãšããã§ãïŒbïŒxïŒ '=ïŒbïŒx + dxïŒ-bïŒxïŒïŒ/ dxã , :
ldarg.1 ldarg.0 callvirt TResult System.Func`2<System.Double,System.Double>::Invoke(T) ret
(dx = 0.000001) ldarg.1 ldarg.0 ldc.r8 1E-06 add callvirt TResult System.Func`2<System.Double,System.Double>::Invoke(T) ldarg.1 ldarg.0 callvirt TResult System.Func`2<System.Double,System.Double>::Invoke(T) sub ldc.r8 0.000001 div ret
, ,
.
ãã¹ãäž
, MathFunction.Tests.
WolframAlpha.NET .
WolframAlpha
WolframAlpha.NET â API
wolframalpha . , , , , . :
public static bool CheckDerivative(string expression, string derivative) { return CheckEquality("diff(" + expression + ")", derivative); } public static bool CheckEquality(string expression1, string expression2) { WolframAlpha wolfram = new WolframAlpha(ConfigurationManager.AppSettings["WolframAlphaAppId"]); string query = "(" + expression1.Replace(" ", "") + ")-(" + expression2.Replace(" ", "") + ")"; QueryResult result = wolfram.Query(query); result.RecalculateResults(); try { double d; return double.TryParse(result.GetPrimaryPod().SubPods[0].Plaintext, out d) && d == 0.0; } catch { return false; } }
, , (MethodInfo):
Domain = AppDomain.CreateDomain("MathFuncDomain"); MathFuncObj = _domain.CreateInstanceFromAndUnwrap(FileName, NamespaceName + "." + ClassName); Type mathFuncObjType = _mathFuncObj.GetType(); Func = mathFuncObjType.GetMethod(FuncName); FuncDerivative = mathFuncObjType.GetMethod(FuncDerivativeName);
:
return (double)Func.Invoke(_mathFuncObj, new object[] { x })
:
if (_domain != null) AppDomain.Unload(Domain); File.Delete(FileName);
IL
IL , , C# csc.exe Release ,
x ^ 3 + sin(3 * ln(x * 1)) + x ^ ln(2 * sin(3 * ln(x))) - 2 * x ^ 3
, C# ILSpy , , .. ã«
(ln(2 * sin(3 * ln(x))) * x ^ -1 + 3 * ln(x) * cos(3 * ln(x)) * sin(3 * ln(x)) ^ -1 * x ^ -1) * x ^ ln(2 * sin(3 * ln(x))) + 3 * cos(3 * ln(x)) * x ^ -1 + -(3 * x ^ 2)
double arg_24_0 = 2.0; double arg_1A_0 = 3.0; double num = Math.Log(x); double num2 = arg_1A_0 * num; double num3 = Math.Sin(num2); double num4 = Math.Log(arg_24_0 * num3); double arg_3B_0 = num4; double num5 = 1.0 / x; double arg_54_0 = arg_3B_0 * num5; double arg_4F_0 = 3.0 * num; num = Math.Cos(num2); return (arg_54_0 + arg_4F_0 * num / num3 * num5) * Math.Pow(x, num4) + num * num5 * 3.0 - x * x * 3.0;
, . , , , double
arg_24_0 = 2.0; , .
, , , , , .
ãããã«
C#, , , - . , , OpenSource
maxima lisp. , F#
codeproject , , . , , , .
Github:
source . :
MathExpressions.NET . . - .
PS , . .
UPDATE: , , .
, .
.