vẽ đồ thị C#
1 using System;
2 using System.Collections;
3
4 namespace EB.Math
5 {
6 public enum Type{Variable,Value,Operator,Function,Result,Bracket,Comma,Error}
7 public struct Symbol
8 {
9 public string m_name;
10 public double m_value;
11 public Type m_type;
12 public override string ToString()
13 {
14 return m_name;
15 }
16 }
17 public delegate Symbol EvaluateFunctionDelegate(string name, params Object[] args);
18 public class Function
19 {
20 public double Result
21 {
22 get
23 {
24 return m_result;
25 }
26 }
27
28 public ArrayList Equation
29 {
30 get
31 {
32 return (ArrayList)m_equation.Clone();
33 }
34 }
35 public ArrayList Postfix
36 {
37 get
38 {
39 return (ArrayList)m_postfix.Clone();
40 }
41 }
42 //Download source code tại Sharecode.vn
43 public EvaluateFunctionDelegate DefaultFunctionEvaluation
44 {
45 set
46 {
47 m_defaultFunctionEvaluation = value;
48 }
49 }
50
51 public bool Error
52 {
53 get
54 {
55 return m_bError;
56 }
57 }
58
59 public string ErrorDescription
60 {
61 get
62 {
63 return m_sErrorDescription;
64 }
65 }
66
67 public ArrayList Variables
68 {
69 get
70 {
71 ArrayList var = new ArrayList();
72 foreach(Symbol sym in m_equation)
73 {
74 if((sym.m_type == Type.Variable) && (!var.Contains(sym)))
75 var.Add(sym);
76 }
77 return var;
78 }
79 set
80 {
81 foreach(Symbol sym in value)
82 {
83 for(int i=0;i<m_postfix.Count;i++)
84 {
85 if((sym.m_name == ((Symbol)m_postfix[i]).m_name) && (((Symbol)m_postfix[i]).m_type == Type.Variable))
86 {
87 Symbol sym1 = (Symbol)m_postfix[i];
88 sym1.m_value = sym.m_value;
89 m_postfix[i] = sym1;
90 }
91 }
92 }
93 }
94 }
95
96 public Function()
97 {}
98
99 public void Parse(string equation)
100 {
101 int state = 1;
102 string temp = "";
103 Symbol ctSymbol;
104
105 m_bError = false;
106 m_sErrorDescription = "None";
107
108 m_equation.Clear();
109 m_postfix.Clear();
110
111 int nPos = 0;
112 //-- Remove all white spaces from the equation string --
113 equation = equation.Trim();
114 while((nPos=equation.IndexOf(' ')) != -1)
115 equation = equation.Remove(nPos,1);
116
117 for(int i=0;i<equation.Length;i++)
118 {
119 switch(state)
120 {
121 case 1:
122 if(Char.IsNumber(equation[i]))
123 {
124 state = 2;
125 temp += equation[i];
126 }
127 else if(Char.IsLetter(equation[i]))
128 {
129 state = 3;
130 temp += equation[i];
131 }
132 else
133 {
134 ctSymbol.m_name = equation[i].ToString();
135 ctSymbol.m_value = 0;
136 switch(ctSymbol.m_name)
137 {
138 case ",":
139 ctSymbol.m_type = Type.Comma;
140 break;
141 case "(":
142 case ")":
143 case "[":
144 case "]":
145 case "{":
146 case "}":
147 ctSymbol.m_type = Type.Bracket;
148 break;
149 default:
150 ctSymbol.m_type = Type.Operator;
151 break;
152 }
153 m_equation.Add(ctSymbol);
154 }
155 break;
156 case 2:
157 if((Char.IsNumber(equation[i])) || (equation[i] == '.'))
158 temp += equation[i];
159 else if(!Char.IsLetter(equation[i]))
160 {
161 state = 1;
162 ctSymbol.m_name = temp;
163 ctSymbol.m_value = Double.Parse(temp);
164 ctSymbol.m_type = Type.Value;
165 m_equation.Add(ctSymbol);
166 ctSymbol.m_name = equation[i].ToString();
167 ctSymbol.m_value = 0;
168 switch(ctSymbol.m_name)
169 {
170 case ",":
171 ctSymbol.m_type = Type.Comma;
172 break;
173 case "(":
174 case ")":
175 case "[":
176 case "]":
177 case "{":
178 case "}":
179 ctSymbol.m_type = Type.Bracket;
180 break;
181 default:
182 ctSymbol.m_type = Type.Operator;
183 break;
184 }
185 m_equation.Add(ctSymbol);
186 temp = "";
187 }
188 break;
189 case 3:
190 if(Char.IsLetterOrDigit(equation[i]))
191 temp += equation[i];
192 else
193 {
194 state = 1;
195 ctSymbol.m_name = temp;
196 ctSymbol.m_value = 0;
197 if(equation[i] == '(')
198 ctSymbol.m_type = Type.Function;
199 else
200 {
201 if(ctSymbol.m_name == "pi")
202 ctSymbol.m_value = System.Math.PI;
203 else if(ctSymbol.m_name == "e")
204 ctSymbol.m_value = System.Math.E;
205 ctSymbol.m_type = Type.Variable;
206 }
207 m_equation.Add(ctSymbol);
208 ctSymbol.m_name = equation[i].ToString();
209 ctSymbol.m_value = 0;
210 switch(ctSymbol.m_name)
211 {
212 case ",":
213 ctSymbol.m_type = Type.Comma;
214 break;
215 case "(":
216 case ")":
217 case "[":
218 case "]":
219 case "{":
220 case "}":
221 ctSymbol.m_type = Type.Bracket;
222 break;
223 default:
224 ctSymbol.m_type = Type.Operator;
225 break;
226 }
227 m_equation.Add(ctSymbol);
228 temp = "";
229 }
230 break;
231 }
232 }
233 if(temp != "")
234 {
235 ctSymbol.m_name = temp;
236 if(state == 2)
237 {
238 ctSymbol.m_value = Double.Parse(temp);
239 ctSymbol.m_type = Type.Value;
240 }
241 else
242 {
243 if(ctSymbol.m_name == "pi")
244 ctSymbol.m_value = System.Math.PI;
245 else if(ctSymbol.m_name == "e")
246 ctSymbol.m_value = System.Math.E;
247 else
248 ctSymbol.m_value = 0;
249 ctSymbol.m_type = Type.Variable;
250 }
251 m_equation.Add(ctSymbol);
252 }
253 }
254
255 public void Infix2Postfix()
256 {
257 Symbol tpSym;
258 Stack tpStack = new Stack();
259 foreach(Symbol sym in m_equation)
260 {
261 if((sym.m_type == Type.Value) || (sym.m_type == Type.Variable))
262 m_postfix.Add(sym);
263 else if((sym.m_name == "(") || (sym.m_name == "[") || (sym.m_name == "{"))
264 tpStack.Push(sym);
265 else if((sym.m_name == ")") || (sym.m_name == "]") || (sym.m_name == "}"))
266 {
267 if(tpStack.Count > 0)
268 {
269 tpSym = (Symbol)tpStack.Pop();
270 while((tpSym.m_name != "(") && (tpSym.m_name != "[") && (tpSym.m_name != "{"))
271 {
272 m_postfix.Add(tpSym);
273 tpSym = (Symbol)tpStack.Pop();
274 }
275 }
276 }
277 else
278 {
279 if(tpStack.Count > 0)
280 {
281 tpSym = (Symbol)tpStack.Pop();
282 while((tpStack.Count != 0) && ((tpSym.m_type == Type.Operator) || (tpSym.m_type == Type.Function) || (tpSym.m_type == Type.Comma)) && (Precedence(tpSym) >= Precedence(sym)))
283 {
284 m_postfix.Add(tpSym);
285 tpSym = (Symbol)tpStack.Pop();
286 }
287 if(((tpSym.m_type == Type.Operator) || (tpSym.m_type == Type.Function) || (tpSym.m_type == Type.Comma)) && (Precedence(tpSym) >= Precedence(sym)))
288 m_postfix.Add(tpSym);
289 else
290 tpStack.Push(tpSym);
291 }
292 tpStack.Push(sym);
293 }
294 }
295 while(tpStack.Count > 0)
296 {
297 tpSym = (Symbol)tpStack.Pop();
298 m_postfix.Add(tpSym);
299 }
300 }
301
302 public void EvaluatePostfix()
303 {
304 Symbol tpSym1, tpSym2, tpResult;
305 Stack tpStack = new Stack();
306 ArrayList fnParam = new ArrayList();
307 m_bError = false;
308 foreach(Symbol sym in m_postfix)
309 {
310 if((sym.m_type == Type.Value) || (sym.m_type == Type.Variable) || (sym.m_type == Type.Result))
311 tpStack.Push(sym);
312 else if(sym.m_type == Type.Operator)
313 {
314 tpSym1 = (Symbol)tpStack.Pop();
315 tpSym2 = (Symbol)tpStack.Pop();
316 tpResult = Evaluate(tpSym2, sym, tpSym1);
317 if(tpResult.m_type == Type.Error)
318 {
319 m_bError = true;
320 m_sErrorDescription = tpResult.m_name;
321 return;
322 }
323 tpStack.Push(tpResult);
324 }
325 else if(sym.m_type == Type.Function)
326 {
327 fnParam.Clear();
328 tpSym1 = (Symbol)tpStack.Pop();
329 if((tpSym1.m_type == Type.Value) || (tpSym1.m_type == Type.Variable) || (tpSym1.m_type == Type.Result))
330 {
331 tpResult = EvaluateFunction(sym.m_name,tpSym1);
332 if(tpResult.m_type == Type.Error)
333 {
334 m_bError = true;
335 m_sErrorDescription = tpResult.m_name;
336 return;
337 }
338 tpStack.Push(tpResult);
339 }
340 else if(tpSym1.m_type == Type.Comma)
341 {
342 while(tpSym1.m_type == Type.Comma)
343 {
344 tpSym1 = (Symbol)tpStack.Pop();
345 fnParam.Add(tpSym1);
346 tpSym1 = (Symbol)tpStack.Pop();
347 }
348 fnParam.Add(tpSym1);
349 tpResult = EvaluateFunction(sym.m_name,fnParam.ToArray());
350 if(tpResult.m_type == Type.Error)
351 {
352 m_bError = true;
353 m_sErrorDescription = tpResult.m_name;
354 return;
355 }
356 tpStack.Push(tpResult);
357 }
358 else
359 {
360 tpStack.Push(tpSym1);
361 tpResult = EvaluateFunction(sym.m_name);
362 if(tpResult.m_type == Type.Error)
363 {
364 m_bError = true;
365 m_sErrorDescription = tpResult.m_name;
366 return;
367 }
368 tpStack.Push(tpResult);
369 }
370 }
371 }
372 if(tpStack.Count == 1)
373 {
374 tpResult = (Symbol)tpStack.Pop();
375 m_result = tpResult.m_value;
376 }
377 }
378
379 protected int Precedence(Symbol sym)
380 {
381 switch(sym.m_type)
382 {
383 case Type.Bracket:
384 return 5;
385 case Type.Function:
386 return 4;
387 case Type.Comma:
388 return 0;
389 }
390 switch(sym.m_name)
391 {
392 case "^":
393 return 3;
394 case "/":
395 case "*":
396 case "%":
397 return 2;
398 case "+":
399 case "-":
400 return 1;
401 }
402 return -1;
403 }
404
405 protected Symbol Evaluate(Symbol sym1, Symbol opr, Symbol sym2)
406 {
407 Symbol result;
408 result.m_name = sym1.m_name + opr.m_name + sym2.m_name;
409 result.m_type = Type.Result;
410 result.m_value = 0;
411 switch(opr.m_name)
412 {
413 case "^":
414 result.m_value = System.Math.Pow(sym1.m_value,sym2.m_value);
415 break;
416 case "/":
417 {
418 //if(sym2.m_value > 0)
419 result.m_value = sym1.m_value / sym2.m_value;
420 //else
421 {
422 // result.m_name = "Divide by Zero.";
423 // result.m_type = Type.Error;
424 }
425 break;
426 }
427 case "*":
428 result.m_value = sym1.m_value * sym2.m_value;
429 break;
430 case "%":
431 result.m_value = sym1.m_value % sym2.m_value;
432 break;
433 case "+":
434 result.m_value = sym1.m_value + sym2.m_value;
435 break;
436 case "-":
437 result.m_value = sym1.m_value - sym2.m_value;
438 break;
439 default:
440 result.m_type = Type.Error;
441 result.m_name = "Không xác định được toán tử " + opr.m_name + ".";
442 break;
443 }
444 return result;
445 }
446
447 protected Symbol EvaluateFunction(string name, params Object[] args)
448 {
449 Symbol result;
450 result.m_name = "";
451 result.m_type = Type.Result;
452 result.m_value = 0;
453 switch(name)
454 {
455 case "cos":
456 if(args.Length == 1)
457 {
458 result.m_name = name + "(" + ((Symbol)args[0]).m_value.ToString() + ")";
459 result.m_value = System.Math.Cos(((Symbol)args[0]).m_value);
460 }
461 else
462 {
463 result.m_name = "Tham số không đúng: "+ name +".";
464 result.m_type = Type.Error;
465 }
466 break;
467 case "sin":
468 if(args.Length == 1)
469 {
470 result.m_name = name + "(" + ((Symbol)args[0]).m_value.ToString() + ")";
471 result.m_value = System.Math.Sin(((Symbol)args[0]).m_value);
472 }
473 else
474 {
475 result.m_name = "Tham số không đúng: "+ name +".";
476 result.m_type = Type.Error;
477 }
478 break;
479 case "tan":
480 if(args.Length == 1)
481 {
482 result.m_name = name + "(" + ((Symbol)args[0]).m_value.ToString() + ")";
483 result.m_value = System.Math.Tan(((Symbol)args[0]).m_value);
484 }
485 else
486 {
487 result.m_name = "Tham số không đúng: "+ name +".";
488 result.m_type = Type.Error;
489 }
490 break;
491 case "cosh":
492 if(args.Length == 1)
493 {
494 result.m_name = name + "(" + ((Symbol)args[0]).m_value.ToString() + ")";
495 result.m_value = System.Math.Cosh(((Symbol)args[0]).m_value);
496 }
497 else
498 {
499 result.m_name = "Tham số không đúng: "+ name +".";
500 result.m_type = Type.Error;
501 }
502 break;
503 case "sinh":
504 if(args.Length == 1)
505 {
506 result.m_name = name + "(" + ((Symbol)args[0]).m_value.ToString() + ")";
507 result.m_value = System.Math.Sinh(((Symbol)args[0]).m_value);
508 }
509 else
510 {
511 result.m_name = "Tham số không đúng: "+ name +".";
512 result.m_type = Type.Error;
513 }
514 break;
515 case "tanh":
516 if(args.Length == 1)
517 {
518 result.m_name = name + "(" + ((Symbol)args[0]).m_value.ToString() + ")";
519 result.m_value = System.Math.Tanh(((Symbol)args[0]).m_value);
520 }
521 else
522 {
523 result.m_name = "Tham số không đúng: "+ name +".";
524 result.m_type = Type.Error;
525 }
526 break;
527 case "log":
528 if(args.Length == 1)
529 {
530 result.m_name = name + "(" + ((Symbol)args[0]).m_value.ToString() + ")";
531 result.m_value = System.Math.Log10(((Symbol)args[0]).m_value);
532 }
533 else
534 {
535 result.m_name = "Tham số không đúng: "+ name +".";
536 result.m_type = Type.Error;
537 }
538 break;
539 case "ln":
540 if(args.Length == 1)
541 {
542 result.m_name = name + "(" + ((Symbol)args[0]).m_value.ToString() + ")";
543 result.m_value = System.Math.Log(((Symbol)args[0]).m_value,2);
544 }
545 else
546 {
547 result.m_name = "Tham số không đúng: "+ name +".";
548 result.m_type = Type.Error;
549 }
550 break;
551 case "logn":
552 if(args.Length == 2)
553 {
554 result.m_name = name + "(" + ((Symbol)args[0]).m_value.ToString() + "'" + ((Symbol)args[1]).m_value.ToString() + ")";
555 result.m_value = System.Math.Log(((Symbol)args[0]).m_value,((Symbol)args[1]).m_value);
556 }
557 else
558 {
559 result.m_name = "Tham số không đúng: "+ name +".";
560 result.m_type = Type.Error;
561 }
562 break;
563 case "sqrt":
564 if(args.Length == 1)
565 {
566 result.m_name = name + "(" + ((Symbol)args[0]).m_value.ToString() + ")";
567 result.m_value = System.Math.Sqrt(((Symbol)args[0]).m_value);
568 }
569 else
570 {
571 result.m_name = "Tham số không đúng: "+ name +".";
572 result.m_type = Type.Error;
573 }
574 break;
575 case "abs":
576 if(args.Length == 1)
577 {
578 result.m_name = name + "(" + ((Symbol)args[0]).m_value.ToString() + ")";
579 result.m_value = System.Math.Abs(((Symbol)args[0]).m_value);
580 }
581 else
582 {
583 result.m_name = "Tham số không đúng: "+ name +".";
584 result.m_type = Type.Error;
585 }
586 break;
587 case "acos":
588 if(args.Length == 1)
589 {
590 result.m_name = name + "(" + ((Symbol)args[0]).m_value.ToString() + ")";
591 result.m_value = System.Math.Acos(((Symbol)args[0]).m_value);
592 }
593 else
594 {
595 result.m_name = "Tham số không đúng: "+ name +".";
596 result.m_type = Type.Error;
597 }
598 break;
599 case "asin":
600 if(args.Length == 1)
601 {
602 result.m_name = name + "(" + ((Symbol)args[0]).m_value.ToString() + ")";
603 result.m_value = System.Math.Asin(((Symbol)args[0]).m_value);
604 }
605 else
606 {
607 result.m_name = "Tham số không đúng: "+ name +".";
608 result.m_type = Type.Error;
609 }
610 break;
611 case "atan":
612 if(args.Length == 1)
613 {
614 result.m_name = name + "(" + ((Symbol)args[0]).m_value.ToString() + ")";
615 result.m_value = System.Math.Atan(((Symbol)args[0]).m_value);
616 }
617 else
618 {
619 result.m_name = "Tham số không đúng: "+ name +".";
620 result.m_type = Type.Error;
621 }
622 break;
623 case "exp":
624 if(args.Length == 1)
625 {
626 result.m_name = name + "(" + ((Symbol)args[0]).m_value.ToString() + ")";
627 result.m_value = System.Math.Exp(((Symbol)args[0]).m_value);
628 }
629 else
630 {
631 result.m_name = "Tham số không đúng: "+ name +".";
632 result.m_type = Type.Error;
633 }
634 break;
635 default:
636 if(m_defaultFunctionEvaluation != null)
637 result = m_defaultFunctionEvaluation(name,args);
638 else
639 {
640 result.m_name = "Không tìm thấy hàm: "+ name +".";
641 result.m_type = Type.Error;
642 }
643 break;
644 }
645 return result;
646 }
647
648 protected bool m_bError = false;
649 protected string m_sErrorDescription = "None";
650 protected double m_result = 0;
651 protected ArrayList m_equation = new ArrayList();
652 protected ArrayList m_postfix = new ArrayList();
653 protected EvaluateFunctionDelegate m_defaultFunctionEvaluation;
654 }
655 }
2 using System.Collections;
3
4 namespace EB.Math
5 {
6 public enum Type{Variable,Value,Operator,Function,Result,Bracket,Comma,Error}
7 public struct Symbol
8 {
9 public string m_name;
10 public double m_value;
11 public Type m_type;
12 public override string ToString()
13 {
14 return m_name;
15 }
16 }
17 public delegate Symbol EvaluateFunctionDelegate(string name, params Object[] args);
18 public class Function
19 {
20 public double Result
21 {
22 get
23 {
24 return m_result;
25 }
26 }
27
28 public ArrayList Equation
29 {
30 get
31 {
32 return (ArrayList)m_equation.Clone();
33 }
34 }
35 public ArrayList Postfix
36 {
37 get
38 {
39 return (ArrayList)m_postfix.Clone();
40 }
41 }
42 //Download source code tại Sharecode.vn
43 public EvaluateFunctionDelegate DefaultFunctionEvaluation
44 {
45 set
46 {
47 m_defaultFunctionEvaluation = value;
48 }
49 }
50
51 public bool Error
52 {
53 get
54 {
55 return m_bError;
56 }
57 }
58
59 public string ErrorDescription
60 {
61 get
62 {
63 return m_sErrorDescription;
64 }
65 }
66
67 public ArrayList Variables
68 {
69 get
70 {
71 ArrayList var = new ArrayList();
72 foreach(Symbol sym in m_equation)
73 {
74 if((sym.m_type == Type.Variable) && (!var.Contains(sym)))
75 var.Add(sym);
76 }
77 return var;
78 }
79 set
80 {
81 foreach(Symbol sym in value)
82 {
83 for(int i=0;i<m_postfix.Count;i++)
84 {
85 if((sym.m_name == ((Symbol)m_postfix[i]).m_name) && (((Symbol)m_postfix[i]).m_type == Type.Variable))
86 {
87 Symbol sym1 = (Symbol)m_postfix[i];
88 sym1.m_value = sym.m_value;
89 m_postfix[i] = sym1;
90 }
91 }
92 }
93 }
94 }
95
96 public Function()
97 {}
98
99 public void Parse(string equation)
100 {
101 int state = 1;
102 string temp = "";
103 Symbol ctSymbol;
104
105 m_bError = false;
106 m_sErrorDescription = "None";
107
108 m_equation.Clear();
109 m_postfix.Clear();
110
111 int nPos = 0;
112 //-- Remove all white spaces from the equation string --
113 equation = equation.Trim();
114 while((nPos=equation.IndexOf(' ')) != -1)
115 equation = equation.Remove(nPos,1);
116
117 for(int i=0;i<equation.Length;i++)
118 {
119 switch(state)
120 {
121 case 1:
122 if(Char.IsNumber(equation[i]))
123 {
124 state = 2;
125 temp += equation[i];
126 }
127 else if(Char.IsLetter(equation[i]))
128 {
129 state = 3;
130 temp += equation[i];
131 }
132 else
133 {
134 ctSymbol.m_name = equation[i].ToString();
135 ctSymbol.m_value = 0;
136 switch(ctSymbol.m_name)
137 {
138 case ",":
139 ctSymbol.m_type = Type.Comma;
140 break;
141 case "(":
142 case ")":
143 case "[":
144 case "]":
145 case "{":
146 case "}":
147 ctSymbol.m_type = Type.Bracket;
148 break;
149 default:
150 ctSymbol.m_type = Type.Operator;
151 break;
152 }
153 m_equation.Add(ctSymbol);
154 }
155 break;
156 case 2:
157 if((Char.IsNumber(equation[i])) || (equation[i] == '.'))
158 temp += equation[i];
159 else if(!Char.IsLetter(equation[i]))
160 {
161 state = 1;
162 ctSymbol.m_name = temp;
163 ctSymbol.m_value = Double.Parse(temp);
164 ctSymbol.m_type = Type.Value;
165 m_equation.Add(ctSymbol);
166 ctSymbol.m_name = equation[i].ToString();
167 ctSymbol.m_value = 0;
168 switch(ctSymbol.m_name)
169 {
170 case ",":
171 ctSymbol.m_type = Type.Comma;
172 break;
173 case "(":
174 case ")":
175 case "[":
176 case "]":
177 case "{":
178 case "}":
179 ctSymbol.m_type = Type.Bracket;
180 break;
181 default:
182 ctSymbol.m_type = Type.Operator;
183 break;
184 }
185 m_equation.Add(ctSymbol);
186 temp = "";
187 }
188 break;
189 case 3:
190 if(Char.IsLetterOrDigit(equation[i]))
191 temp += equation[i];
192 else
193 {
194 state = 1;
195 ctSymbol.m_name = temp;
196 ctSymbol.m_value = 0;
197 if(equation[i] == '(')
198 ctSymbol.m_type = Type.Function;
199 else
200 {
201 if(ctSymbol.m_name == "pi")
202 ctSymbol.m_value = System.Math.PI;
203 else if(ctSymbol.m_name == "e")
204 ctSymbol.m_value = System.Math.E;
205 ctSymbol.m_type = Type.Variable;
206 }
207 m_equation.Add(ctSymbol);
208 ctSymbol.m_name = equation[i].ToString();
209 ctSymbol.m_value = 0;
210 switch(ctSymbol.m_name)
211 {
212 case ",":
213 ctSymbol.m_type = Type.Comma;
214 break;
215 case "(":
216 case ")":
217 case "[":
218 case "]":
219 case "{":
220 case "}":
221 ctSymbol.m_type = Type.Bracket;
222 break;
223 default:
224 ctSymbol.m_type = Type.Operator;
225 break;
226 }
227 m_equation.Add(ctSymbol);
228 temp = "";
229 }
230 break;
231 }
232 }
233 if(temp != "")
234 {
235 ctSymbol.m_name = temp;
236 if(state == 2)
237 {
238 ctSymbol.m_value = Double.Parse(temp);
239 ctSymbol.m_type = Type.Value;
240 }
241 else
242 {
243 if(ctSymbol.m_name == "pi")
244 ctSymbol.m_value = System.Math.PI;
245 else if(ctSymbol.m_name == "e")
246 ctSymbol.m_value = System.Math.E;
247 else
248 ctSymbol.m_value = 0;
249 ctSymbol.m_type = Type.Variable;
250 }
251 m_equation.Add(ctSymbol);
252 }
253 }
254
255 public void Infix2Postfix()
256 {
257 Symbol tpSym;
258 Stack tpStack = new Stack();
259 foreach(Symbol sym in m_equation)
260 {
261 if((sym.m_type == Type.Value) || (sym.m_type == Type.Variable))
262 m_postfix.Add(sym);
263 else if((sym.m_name == "(") || (sym.m_name == "[") || (sym.m_name == "{"))
264 tpStack.Push(sym);
265 else if((sym.m_name == ")") || (sym.m_name == "]") || (sym.m_name == "}"))
266 {
267 if(tpStack.Count > 0)
268 {
269 tpSym = (Symbol)tpStack.Pop();
270 while((tpSym.m_name != "(") && (tpSym.m_name != "[") && (tpSym.m_name != "{"))
271 {
272 m_postfix.Add(tpSym);
273 tpSym = (Symbol)tpStack.Pop();
274 }
275 }
276 }
277 else
278 {
279 if(tpStack.Count > 0)
280 {
281 tpSym = (Symbol)tpStack.Pop();
282 while((tpStack.Count != 0) && ((tpSym.m_type == Type.Operator) || (tpSym.m_type == Type.Function) || (tpSym.m_type == Type.Comma)) && (Precedence(tpSym) >= Precedence(sym)))
283 {
284 m_postfix.Add(tpSym);
285 tpSym = (Symbol)tpStack.Pop();
286 }
287 if(((tpSym.m_type == Type.Operator) || (tpSym.m_type == Type.Function) || (tpSym.m_type == Type.Comma)) && (Precedence(tpSym) >= Precedence(sym)))
288 m_postfix.Add(tpSym);
289 else
290 tpStack.Push(tpSym);
291 }
292 tpStack.Push(sym);
293 }
294 }
295 while(tpStack.Count > 0)
296 {
297 tpSym = (Symbol)tpStack.Pop();
298 m_postfix.Add(tpSym);
299 }
300 }
301
302 public void EvaluatePostfix()
303 {
304 Symbol tpSym1, tpSym2, tpResult;
305 Stack tpStack = new Stack();
306 ArrayList fnParam = new ArrayList();
307 m_bError = false;
308 foreach(Symbol sym in m_postfix)
309 {
310 if((sym.m_type == Type.Value) || (sym.m_type == Type.Variable) || (sym.m_type == Type.Result))
311 tpStack.Push(sym);
312 else if(sym.m_type == Type.Operator)
313 {
314 tpSym1 = (Symbol)tpStack.Pop();
315 tpSym2 = (Symbol)tpStack.Pop();
316 tpResult = Evaluate(tpSym2, sym, tpSym1);
317 if(tpResult.m_type == Type.Error)
318 {
319 m_bError = true;
320 m_sErrorDescription = tpResult.m_name;
321 return;
322 }
323 tpStack.Push(tpResult);
324 }
325 else if(sym.m_type == Type.Function)
326 {
327 fnParam.Clear();
328 tpSym1 = (Symbol)tpStack.Pop();
329 if((tpSym1.m_type == Type.Value) || (tpSym1.m_type == Type.Variable) || (tpSym1.m_type == Type.Result))
330 {
331 tpResult = EvaluateFunction(sym.m_name,tpSym1);
332 if(tpResult.m_type == Type.Error)
333 {
334 m_bError = true;
335 m_sErrorDescription = tpResult.m_name;
336 return;
337 }
338 tpStack.Push(tpResult);
339 }
340 else if(tpSym1.m_type == Type.Comma)
341 {
342 while(tpSym1.m_type == Type.Comma)
343 {
344 tpSym1 = (Symbol)tpStack.Pop();
345 fnParam.Add(tpSym1);
346 tpSym1 = (Symbol)tpStack.Pop();
347 }
348 fnParam.Add(tpSym1);
349 tpResult = EvaluateFunction(sym.m_name,fnParam.ToArray());
350 if(tpResult.m_type == Type.Error)
351 {
352 m_bError = true;
353 m_sErrorDescription = tpResult.m_name;
354 return;
355 }
356 tpStack.Push(tpResult);
357 }
358 else
359 {
360 tpStack.Push(tpSym1);
361 tpResult = EvaluateFunction(sym.m_name);
362 if(tpResult.m_type == Type.Error)
363 {
364 m_bError = true;
365 m_sErrorDescription = tpResult.m_name;
366 return;
367 }
368 tpStack.Push(tpResult);
369 }
370 }
371 }
372 if(tpStack.Count == 1)
373 {
374 tpResult = (Symbol)tpStack.Pop();
375 m_result = tpResult.m_value;
376 }
377 }
378
379 protected int Precedence(Symbol sym)
380 {
381 switch(sym.m_type)
382 {
383 case Type.Bracket:
384 return 5;
385 case Type.Function:
386 return 4;
387 case Type.Comma:
388 return 0;
389 }
390 switch(sym.m_name)
391 {
392 case "^":
393 return 3;
394 case "/":
395 case "*":
396 case "%":
397 return 2;
398 case "+":
399 case "-":
400 return 1;
401 }
402 return -1;
403 }
404
405 protected Symbol Evaluate(Symbol sym1, Symbol opr, Symbol sym2)
406 {
407 Symbol result;
408 result.m_name = sym1.m_name + opr.m_name + sym2.m_name;
409 result.m_type = Type.Result;
410 result.m_value = 0;
411 switch(opr.m_name)
412 {
413 case "^":
414 result.m_value = System.Math.Pow(sym1.m_value,sym2.m_value);
415 break;
416 case "/":
417 {
418 //if(sym2.m_value > 0)
419 result.m_value = sym1.m_value / sym2.m_value;
420 //else
421 {
422 // result.m_name = "Divide by Zero.";
423 // result.m_type = Type.Error;
424 }
425 break;
426 }
427 case "*":
428 result.m_value = sym1.m_value * sym2.m_value;
429 break;
430 case "%":
431 result.m_value = sym1.m_value % sym2.m_value;
432 break;
433 case "+":
434 result.m_value = sym1.m_value + sym2.m_value;
435 break;
436 case "-":
437 result.m_value = sym1.m_value - sym2.m_value;
438 break;
439 default:
440 result.m_type = Type.Error;
441 result.m_name = "Không xác định được toán tử " + opr.m_name + ".";
442 break;
443 }
444 return result;
445 }
446
447 protected Symbol EvaluateFunction(string name, params Object[] args)
448 {
449 Symbol result;
450 result.m_name = "";
451 result.m_type = Type.Result;
452 result.m_value = 0;
453 switch(name)
454 {
455 case "cos":
456 if(args.Length == 1)
457 {
458 result.m_name = name + "(" + ((Symbol)args[0]).m_value.ToString() + ")";
459 result.m_value = System.Math.Cos(((Symbol)args[0]).m_value);
460 }
461 else
462 {
463 result.m_name = "Tham số không đúng: "+ name +".";
464 result.m_type = Type.Error;
465 }
466 break;
467 case "sin":
468 if(args.Length == 1)
469 {
470 result.m_name = name + "(" + ((Symbol)args[0]).m_value.ToString() + ")";
471 result.m_value = System.Math.Sin(((Symbol)args[0]).m_value);
472 }
473 else
474 {
475 result.m_name = "Tham số không đúng: "+ name +".";
476 result.m_type = Type.Error;
477 }
478 break;
479 case "tan":
480 if(args.Length == 1)
481 {
482 result.m_name = name + "(" + ((Symbol)args[0]).m_value.ToString() + ")";
483 result.m_value = System.Math.Tan(((Symbol)args[0]).m_value);
484 }
485 else
486 {
487 result.m_name = "Tham số không đúng: "+ name +".";
488 result.m_type = Type.Error;
489 }
490 break;
491 case "cosh":
492 if(args.Length == 1)
493 {
494 result.m_name = name + "(" + ((Symbol)args[0]).m_value.ToString() + ")";
495 result.m_value = System.Math.Cosh(((Symbol)args[0]).m_value);
496 }
497 else
498 {
499 result.m_name = "Tham số không đúng: "+ name +".";
500 result.m_type = Type.Error;
501 }
502 break;
503 case "sinh":
504 if(args.Length == 1)
505 {
506 result.m_name = name + "(" + ((Symbol)args[0]).m_value.ToString() + ")";
507 result.m_value = System.Math.Sinh(((Symbol)args[0]).m_value);
508 }
509 else
510 {
511 result.m_name = "Tham số không đúng: "+ name +".";
512 result.m_type = Type.Error;
513 }
514 break;
515 case "tanh":
516 if(args.Length == 1)
517 {
518 result.m_name = name + "(" + ((Symbol)args[0]).m_value.ToString() + ")";
519 result.m_value = System.Math.Tanh(((Symbol)args[0]).m_value);
520 }
521 else
522 {
523 result.m_name = "Tham số không đúng: "+ name +".";
524 result.m_type = Type.Error;
525 }
526 break;
527 case "log":
528 if(args.Length == 1)
529 {
530 result.m_name = name + "(" + ((Symbol)args[0]).m_value.ToString() + ")";
531 result.m_value = System.Math.Log10(((Symbol)args[0]).m_value);
532 }
533 else
534 {
535 result.m_name = "Tham số không đúng: "+ name +".";
536 result.m_type = Type.Error;
537 }
538 break;
539 case "ln":
540 if(args.Length == 1)
541 {
542 result.m_name = name + "(" + ((Symbol)args[0]).m_value.ToString() + ")";
543 result.m_value = System.Math.Log(((Symbol)args[0]).m_value,2);
544 }
545 else
546 {
547 result.m_name = "Tham số không đúng: "+ name +".";
548 result.m_type = Type.Error;
549 }
550 break;
551 case "logn":
552 if(args.Length == 2)
553 {
554 result.m_name = name + "(" + ((Symbol)args[0]).m_value.ToString() + "'" + ((Symbol)args[1]).m_value.ToString() + ")";
555 result.m_value = System.Math.Log(((Symbol)args[0]).m_value,((Symbol)args[1]).m_value);
556 }
557 else
558 {
559 result.m_name = "Tham số không đúng: "+ name +".";
560 result.m_type = Type.Error;
561 }
562 break;
563 case "sqrt":
564 if(args.Length == 1)
565 {
566 result.m_name = name + "(" + ((Symbol)args[0]).m_value.ToString() + ")";
567 result.m_value = System.Math.Sqrt(((Symbol)args[0]).m_value);
568 }
569 else
570 {
571 result.m_name = "Tham số không đúng: "+ name +".";
572 result.m_type = Type.Error;
573 }
574 break;
575 case "abs":
576 if(args.Length == 1)
577 {
578 result.m_name = name + "(" + ((Symbol)args[0]).m_value.ToString() + ")";
579 result.m_value = System.Math.Abs(((Symbol)args[0]).m_value);
580 }
581 else
582 {
583 result.m_name = "Tham số không đúng: "+ name +".";
584 result.m_type = Type.Error;
585 }
586 break;
587 case "acos":
588 if(args.Length == 1)
589 {
590 result.m_name = name + "(" + ((Symbol)args[0]).m_value.ToString() + ")";
591 result.m_value = System.Math.Acos(((Symbol)args[0]).m_value);
592 }
593 else
594 {
595 result.m_name = "Tham số không đúng: "+ name +".";
596 result.m_type = Type.Error;
597 }
598 break;
599 case "asin":
600 if(args.Length == 1)
601 {
602 result.m_name = name + "(" + ((Symbol)args[0]).m_value.ToString() + ")";
603 result.m_value = System.Math.Asin(((Symbol)args[0]).m_value);
604 }
605 else
606 {
607 result.m_name = "Tham số không đúng: "+ name +".";
608 result.m_type = Type.Error;
609 }
610 break;
611 case "atan":
612 if(args.Length == 1)
613 {
614 result.m_name = name + "(" + ((Symbol)args[0]).m_value.ToString() + ")";
615 result.m_value = System.Math.Atan(((Symbol)args[0]).m_value);
616 }
617 else
618 {
619 result.m_name = "Tham số không đúng: "+ name +".";
620 result.m_type = Type.Error;
621 }
622 break;
623 case "exp":
624 if(args.Length == 1)
625 {
626 result.m_name = name + "(" + ((Symbol)args[0]).m_value.ToString() + ")";
627 result.m_value = System.Math.Exp(((Symbol)args[0]).m_value);
628 }
629 else
630 {
631 result.m_name = "Tham số không đúng: "+ name +".";
632 result.m_type = Type.Error;
633 }
634 break;
635 default:
636 if(m_defaultFunctionEvaluation != null)
637 result = m_defaultFunctionEvaluation(name,args);
638 else
639 {
640 result.m_name = "Không tìm thấy hàm: "+ name +".";
641 result.m_type = Type.Error;
642 }
643 break;
644 }
645 return result;
646 }
647
648 protected bool m_bError = false;
649 protected string m_sErrorDescription = "None";
650 protected double m_result = 0;
651 protected ArrayList m_equation = new ArrayList();
652 protected ArrayList m_postfix = new ArrayList();
653 protected EvaluateFunctionDelegate m_defaultFunctionEvaluation;
654 }
655 }