• Skip to content
  • Skip to link menu
KDE API Reference
  • KDE API Reference
  • kdeutils API Reference
  • KDE Home
  • Contact Us
 

kcalc

  • sources
  • kde-4.12
  • kdeutils
  • kcalc
kcalc_core.cpp
Go to the documentation of this file.
1 /*
2 Copyright (C) 2001 - 2013 Evan Teran
3  evan.teran@gmail.com
4 
5 Copyright (C) 2003 - 2005 Klaus Niederkrueger
6  kniederk@math.uni-koeln.de
7 
8 Copyright (C) 1996 - 2000 Bernd Johannes Wuebben
9  wuebben@kde.org
10 
11 Copyright (C) 1995 Martin Bartlett
12 
13 This program is free software; you can redistribute it and/or
14 modify it under the terms of the GNU General Public License as
15 published by the Free Software Foundation; either version 2 of
16 the License, or (at your option) any later version.
17 
18 This program is distributed in the hope that it will be useful,
19 but WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 GNU General Public License for more details.
22 
23 You should have received a copy of the GNU General Public License
24 along with this program. If not, see <http://www.gnu.org/licenses/>.
25 */
26 
27 #include "kcalc_core.h"
28 #include <kdebug.h>
29 #include <klocale.h>
30 #include <kmessagebox.h>
31 
32 namespace {
33 
34 KNumber Deg2Rad(const KNumber &x) {
35  return x * (KNumber::Pi() / KNumber(180));
36 }
37 
38 KNumber Gra2Rad(const KNumber &x) {
39  return x * (KNumber::Pi() / KNumber(200));
40 }
41 
42 KNumber Rad2Deg(const KNumber &x) {
43  return x * (KNumber(180) / KNumber::Pi());
44 }
45 
46 KNumber Rad2Gra(const KNumber &x) {
47  return x * (KNumber(200) / KNumber::Pi());
48 }
49 
50 bool error_;
51 
52 KNumber ExecOr(const KNumber &left_op, const KNumber &right_op) {
53  return left_op | right_op;
54 }
55 
56 KNumber ExecXor(const KNumber &left_op, const KNumber &right_op) {
57  return left_op ^ right_op;
58 }
59 
60 KNumber ExecAnd(const KNumber &left_op, const KNumber &right_op) {
61  return left_op & right_op;
62 }
63 
64 KNumber ExecLsh(const KNumber &left_op, const KNumber &right_op) {
65  return left_op << right_op;
66 }
67 
68 KNumber ExecRsh(const KNumber &left_op, const KNumber &right_op) {
69  return left_op >> right_op;
70 }
71 
72 KNumber ExecAdd(const KNumber &left_op, const KNumber &right_op) {
73  return left_op + right_op;
74 }
75 
76 KNumber ExecSubtract(const KNumber &left_op, const KNumber &right_op) {
77  return left_op - right_op;
78 }
79 
80 KNumber ExecMultiply(const KNumber &left_op, const KNumber &right_op) {
81  return left_op * right_op;
82 }
83 
84 KNumber ExecDivide(const KNumber &left_op, const KNumber &right_op) {
85  return left_op / right_op;
86 }
87 
88 KNumber ExecMod(const KNumber &left_op, const KNumber &right_op) {
89  return left_op % right_op;
90 }
91 
92 KNumber ExecIntDiv(const KNumber &left_op, const KNumber &right_op) {
93  return (left_op / right_op).integerPart();
94 }
95 
96 KNumber ExecBinom(const KNumber &left_op, const KNumber &right_op) {
97  return left_op.bin(right_op);
98 }
99 
100 KNumber ExecPower(const KNumber &left_op, const KNumber &right_op) {
101  return left_op.pow(right_op);
102 }
103 
104 KNumber ExecPwrRoot(const KNumber &left_op, const KNumber &right_op) {
105  return left_op.pow(KNumber::One / right_op);
106 }
107 
108 KNumber ExecAddP(const KNumber &left_op, const KNumber &right_op) {
109  return left_op * (KNumber::One + right_op / KNumber(100));
110 }
111 
112 KNumber ExecSubP(const KNumber &left_op, const KNumber &right_op) {
113  return left_op * (KNumber::One - right_op / KNumber(100));
114 }
115 
116 KNumber ExecMultiplyP(const KNumber &left_op, const KNumber &right_op) {
117  return left_op * right_op / KNumber(100);
118 }
119 
120 KNumber ExecDivideP(const KNumber &left_op, const KNumber &right_op) {
121  return left_op * KNumber(100) / right_op;
122 }
123 
124 // move a number into the interval [0,360) by adding multiples of 360
125 KNumber moveIntoDegInterval(const KNumber &num) {
126  KNumber tmp_num = num - (num / KNumber(360)).integerPart() * KNumber(360);
127  if (tmp_num < KNumber::Zero)
128  return tmp_num + KNumber(360);
129  return tmp_num;
130 }
131 
132 // move a number into the interval [0,400) by adding multiples of 400
133 KNumber moveIntoGradInterval(const KNumber &num) {
134  KNumber tmp_num = num - (num / KNumber(400)).integerPart() * KNumber(400);
135  if (tmp_num < KNumber::Zero)
136  return tmp_num + KNumber(400);
137  return tmp_num;
138 }
139 
140 typedef KNumber(*Arith)(const KNumber &, const KNumber &);
141 typedef KNumber(*Prcnt)(const KNumber &, const KNumber &);
142 
143 struct operator_data {
144  int precedence; // priority of operators in " enum Operation"
145  Arith arith_ptr;
146  Prcnt prcnt_ptr;
147 };
148 
149 // build precedence list
150 const struct operator_data Operator[] = {
151  { 0, NULL, NULL}, // FUNC_EQUAL
152  { 0, NULL, NULL}, // FUNC_PERCENT
153  { 0, NULL, NULL}, // FUNC_BRACKET
154  { 1, ExecOr, NULL}, // FUNC_OR
155  { 2, ExecXor, NULL}, // FUNC_XOR
156  { 3, ExecAnd, NULL}, // FUNC_AND
157  { 4, ExecLsh, NULL}, // FUNC_LSH
158  { 4, ExecRsh, NULL}, // FUNC_RSH
159  { 5, ExecAdd, ExecAddP}, // FUNC_ADD
160  { 5, ExecSubtract, ExecSubP}, // FUNC_SUBTRACT
161  { 6, ExecMultiply, ExecMultiplyP}, // FUNC_MULTIPLY
162  { 6, ExecDivide, ExecDivideP}, // FUNC_DIVIDE
163  { 6, ExecMod, NULL}, // FUNC_MOD
164  { 6, ExecIntDiv, NULL}, // FUNC_INTDIV
165  { 7, ExecBinom, NULL}, // FUNC_BINOM
166  { 7, ExecPower, NULL}, // FUNC_POWER
167  { 7, ExecPwrRoot, NULL} // FUNC_PWR_ROOT
168 };
169 
170 }
171 
172 
173 CalcEngine::CalcEngine() : percent_mode_(false) {
174 
175  last_number_ = KNumber::Zero;
176  error_ = false;
177 }
178 
179 KNumber CalcEngine::lastOutput(bool &error) const {
180  error = error_;
181  return last_number_;
182 }
183 
184 void CalcEngine::ArcCosDeg(const KNumber &input)
185 {
186  if (input.type() == KNumber::TYPE_ERROR || input < -KNumber::One || input > KNumber::One) {
187  last_number_ = KNumber::NaN;
188  return;
189  }
190 
191  if (input.type() == KNumber::TYPE_INTEGER) {
192  if (input == KNumber::One) {
193  last_number_ = KNumber::Zero;
194  return;
195  }
196  if (input == - KNumber::One) {
197  last_number_ = KNumber(180);
198  return;
199  }
200  if (input == KNumber::Zero) {
201  last_number_ = KNumber(90);
202  return;
203  }
204  }
205  last_number_ = Rad2Deg(input.acos());
206 }
207 
208 void CalcEngine::ArcCosRad(const KNumber &input)
209 {
210  if (input.type() == KNumber::TYPE_ERROR || input < -KNumber::One || input > KNumber::One) {
211  last_number_ = KNumber::NaN;
212  return;
213  }
214  last_number_ = input.acos();
215 }
216 
217 void CalcEngine::ArcCosGrad(const KNumber &input)
218 {
219  if (input.type() == KNumber::TYPE_ERROR || input < -KNumber::One || input > KNumber::One) {
220  last_number_ = KNumber::NaN;
221  return;
222  }
223  if (input.type() == KNumber::TYPE_INTEGER) {
224  if (input == KNumber::One) {
225  last_number_ = KNumber::Zero;
226  return;
227  }
228  if (input == - KNumber::One) {
229  last_number_ = KNumber(200);
230  return;
231  }
232  if (input == KNumber::Zero) {
233  last_number_ = KNumber(100);
234  return;
235  }
236  }
237  last_number_ = Rad2Gra(input.acos());
238 }
239 
240 void CalcEngine::ArcSinDeg(const KNumber &input)
241 {
242  if (input.type() == KNumber::TYPE_ERROR ||
243  input < -KNumber::One || input > KNumber::One) {
244  last_number_ = KNumber::NaN;
245  return;
246  }
247  if (input.type() == KNumber::TYPE_INTEGER) {
248  if (input == KNumber::One) {
249  last_number_ = KNumber(90);
250  return;
251  }
252  if (input == - KNumber::One) {
253  last_number_ = KNumber(-90);
254  return;
255  }
256  if (input == KNumber::Zero) {
257  last_number_ = KNumber::Zero;
258  return;
259  }
260  }
261  last_number_ = Rad2Deg(input.asin());
262 }
263 
264 void CalcEngine::ArcSinRad(const KNumber &input)
265 {
266  if (input.type() == KNumber::TYPE_ERROR ||
267  input < -KNumber::One || input > KNumber::One) {
268  last_number_ = KNumber::NaN;
269  return;
270  }
271  last_number_ = input.asin();
272 }
273 
274 void CalcEngine::ArcSinGrad(const KNumber &input)
275 {
276  if (input.type() == KNumber::TYPE_ERROR ||
277  input < -KNumber::One || input > KNumber::One) {
278  last_number_ = KNumber::NaN;
279  return;
280  }
281  if (input.type() == KNumber::TYPE_INTEGER) {
282  if (input == KNumber::One) {
283  last_number_ = KNumber(100);
284  return;
285  }
286  if (input == - KNumber::One) {
287  last_number_ = KNumber(-100);
288  return;
289  }
290  if (input == KNumber::Zero) {
291  last_number_ = KNumber::Zero;
292  return;
293  }
294  }
295  last_number_ = Rad2Gra(input.asin());
296 }
297 
298 void CalcEngine::ArcTangensDeg(const KNumber &input)
299 {
300  if (input.type() == KNumber::TYPE_ERROR) {
301  if (input == KNumber::NaN) last_number_ = KNumber::NaN;
302  if (input == KNumber::PosInfinity) last_number_ = KNumber(90);
303  if (input == KNumber::NegInfinity) last_number_ = KNumber(-90);
304  return;
305  }
306 
307  last_number_ = Rad2Deg(input.atan());
308 }
309 
310 void CalcEngine::ArcTangensRad(const KNumber &input)
311 {
312  if (input.type() == KNumber::TYPE_ERROR) {
313  if (input == KNumber::NaN) last_number_ = KNumber::NaN;
314  if (input == KNumber::PosInfinity)
315  last_number_ = KNumber::Pi() / KNumber(2);
316  if (input == KNumber::NegInfinity)
317  last_number_ = -KNumber::Pi() / KNumber(2);
318  return;
319  }
320 
321  last_number_ = input.atan();
322 }
323 
324 void CalcEngine::ArcTangensGrad(const KNumber &input)
325 {
326  if (input.type() == KNumber::TYPE_ERROR) {
327  if (input == KNumber::NaN) last_number_ = KNumber::NaN;
328  if (input == KNumber::PosInfinity) last_number_ = KNumber(100);
329  if (input == KNumber::NegInfinity) last_number_ = KNumber(-100);
330  return;
331  }
332 
333  last_number_ = Rad2Gra(input.atan());
334 }
335 
336 void CalcEngine::AreaCosHyp(const KNumber &input)
337 {
338  if (input.type() == KNumber::TYPE_ERROR) {
339  if (input == KNumber::NaN) last_number_ = KNumber::NaN;
340  if (input == KNumber::PosInfinity) last_number_ = KNumber::PosInfinity;
341  if (input == KNumber::NegInfinity) last_number_ = KNumber::NaN;
342  return;
343  }
344 
345  if (input < KNumber::One) {
346  last_number_ = KNumber::NaN;
347  return;
348  }
349  if (input == KNumber::One) {
350  last_number_ = KNumber::Zero;
351  return;
352  }
353  last_number_ = input.acosh();
354 }
355 
356 void CalcEngine::AreaSinHyp(const KNumber &input)
357 {
358  if (input.type() == KNumber::TYPE_ERROR) {
359  if (input == KNumber::NaN) last_number_ = KNumber::NaN;
360  if (input == KNumber::PosInfinity) last_number_ = KNumber::PosInfinity;
361  if (input == KNumber::NegInfinity) last_number_ = KNumber::NegInfinity;
362  return;
363  }
364 
365  if (input == KNumber::Zero) {
366  last_number_ = KNumber::Zero;
367  return;
368  }
369  last_number_ = input.asinh();
370 }
371 
372 void CalcEngine::AreaTangensHyp(const KNumber &input)
373 {
374  if (input.type() == KNumber::TYPE_ERROR) {
375  last_number_ = KNumber::NaN;
376  return;
377  }
378 
379  if (input < -KNumber::One || input > KNumber::One) {
380  last_number_ = KNumber::NaN;
381  return;
382  }
383  if (input == KNumber::One) {
384  last_number_ = KNumber::PosInfinity;
385  return;
386  }
387  if (input == - KNumber::One) {
388  last_number_ = KNumber::NegInfinity;
389  return;
390  }
391  last_number_ = input.atanh();
392 }
393 
394 void CalcEngine::Complement(const KNumber &input)
395 {
396  if (input.type() != KNumber::TYPE_INTEGER) {
397  last_number_ = KNumber::NaN;
398  return;
399  }
400 
401  last_number_ = ~input;
402 }
403 
404 void CalcEngine::CosDeg(const KNumber &input)
405 {
406  if (input.type() == KNumber::TYPE_ERROR) {
407  last_number_ = KNumber::NaN;
408  return;
409  }
410 
411  KNumber trunc_input = moveIntoDegInterval(input);
412 
413  if (trunc_input.type() == KNumber::TYPE_INTEGER) {
414  KNumber mult = trunc_input / KNumber(90);
415  if (mult.type() == KNumber::TYPE_INTEGER) {
416  if (mult == KNumber::Zero)
417  last_number_ = KNumber::One;
418  else if (mult == KNumber::One)
419  last_number_ = KNumber::Zero;
420  else if (mult == KNumber(2))
421  last_number_ = KNumber::NegOne;
422  else if (mult == KNumber(3))
423  last_number_ = KNumber::Zero;
424  else kDebug() << "Something wrong in CalcEngine::CosDeg";
425  return;
426  }
427  }
428 
429  trunc_input = Deg2Rad(trunc_input);
430  last_number_ = trunc_input.cos();
431 }
432 
433 void CalcEngine::CosRad(const KNumber &input)
434 {
435  if (input.type() == KNumber::TYPE_ERROR) {
436  last_number_ = KNumber::NaN;
437  return;
438  }
439 
440  last_number_ = input.cos();
441 }
442 
443 void CalcEngine::CosGrad(const KNumber &input)
444 {
445  if (input.type() == KNumber::TYPE_ERROR) {
446  last_number_ = KNumber::NaN;
447  return;
448  }
449  KNumber trunc_input = moveIntoGradInterval(input);
450  if (trunc_input.type() == KNumber::TYPE_INTEGER) {
451  KNumber mult = trunc_input / KNumber(100);
452  if (mult.type() == KNumber::TYPE_INTEGER) {
453  if (mult == KNumber::Zero)
454  last_number_ = KNumber::One;
455  else if (mult == KNumber::One)
456  last_number_ = KNumber::Zero;
457  else if (mult == KNumber(2))
458  last_number_ = KNumber::NegOne;
459  else if (mult == KNumber(3))
460  last_number_ = KNumber::Zero;
461  else kDebug() << "Something wrong in CalcEngine::CosGrad";
462  return;
463  }
464  }
465  trunc_input = Gra2Rad(trunc_input);
466 
467  last_number_ = trunc_input.cos();
468 }
469 
470 void CalcEngine::CosHyp(const KNumber &input)
471 {
472  if (input.type() == KNumber::TYPE_ERROR) {
473  if (input == KNumber::NaN) last_number_ = KNumber::NaN;
474  if (input == KNumber::PosInfinity) last_number_ = KNumber::PosInfinity;
475  // YES, this should be *positive* infinity. We mimic the behavior of
476  // libc which says the following for cosh
477  //
478  // "If x is positive infinity or negative infinity, positive infinity is returned."
479  if (input == KNumber::NegInfinity) last_number_ = KNumber::PosInfinity;
480  return;
481  }
482 
483  last_number_ = input.cosh();
484 }
485 
486 void CalcEngine::Cube(const KNumber &input)
487 {
488  last_number_ = input * input * input;
489 }
490 
491 void CalcEngine::CubeRoot(const KNumber &input)
492 {
493  last_number_ = input.cbrt();
494 }
495 
496 void CalcEngine::Exp(const KNumber &input)
497 {
498  if (input.type() == KNumber::TYPE_ERROR) {
499  if (input == KNumber::NaN) last_number_ = KNumber::NaN;
500  if (input == KNumber::PosInfinity) last_number_ = KNumber::PosInfinity;
501  if (input == KNumber::NegInfinity) last_number_ = KNumber::Zero;
502  return;
503  }
504  last_number_ = KNumber::Euler().pow(input);
505 }
506 
507 void CalcEngine::Exp10(const KNumber &input)
508 {
509  if (input.type() == KNumber::TYPE_ERROR) {
510  if (input == KNumber::NaN) last_number_ = KNumber::NaN;
511  if (input == KNumber::PosInfinity) last_number_ = KNumber::PosInfinity;
512  if (input == KNumber::NegInfinity) last_number_ = KNumber::Zero;
513  return;
514  }
515  last_number_ = KNumber(10).pow(input);
516 }
517 
518 
519 void CalcEngine::Factorial(const KNumber &input)
520 {
521  if (input == KNumber::PosInfinity) return;
522  if (input < KNumber::Zero || input.type() == KNumber::TYPE_ERROR) {
523  error_ = true;
524  last_number_ = KNumber::NaN;
525  return;
526  }
527 
528  last_number_ = input.integerPart().factorial();
529 }
530 
531 void CalcEngine::InvertSign(const KNumber &input)
532 {
533  last_number_ = -input;
534 }
535 
536 void CalcEngine::Ln(const KNumber &input)
537 {
538  if (input < KNumber::Zero)
539  last_number_ = KNumber::NaN;
540  else if (input == KNumber::Zero)
541  last_number_ = KNumber::NegInfinity;
542  else if (input == KNumber::One)
543  last_number_ = KNumber::Zero;
544  else {
545  last_number_ = input.ln();
546  }
547 }
548 
549 void CalcEngine::Log10(const KNumber &input)
550 {
551  if (input < KNumber::Zero)
552  last_number_ = KNumber::NaN;
553  else if (input == KNumber::Zero)
554  last_number_ = KNumber::NegInfinity;
555  else if (input == KNumber::One)
556  last_number_ = KNumber::Zero;
557  else {
558  last_number_ = input.log10();
559  }
560 }
561 
562 void CalcEngine::ParenClose(KNumber input)
563 {
564  // evaluate stack until corresponding opening bracket
565  while (!stack_.isEmpty()) {
566  Node tmp_node = stack_.pop();
567  if (tmp_node.operation == FUNC_BRACKET)
568  break;
569  input = evalOperation(tmp_node.number, tmp_node.operation, input);
570  }
571  last_number_ = input;
572  return;
573 }
574 
575 void CalcEngine::ParenOpen(const KNumber &input)
576 {
577  enterOperation(input, FUNC_BRACKET);
578 }
579 
580 void CalcEngine::Reciprocal(const KNumber &input)
581 {
582  last_number_ = KNumber::One / input;
583 }
584 
585 
586 void CalcEngine::SinDeg(const KNumber &input)
587 {
588  if (input.type() == KNumber::TYPE_ERROR) {
589  last_number_ = KNumber::NaN;
590  return;
591  }
592 
593  KNumber trunc_input = moveIntoDegInterval(input);
594  if (trunc_input.type() == KNumber::TYPE_INTEGER) {
595  KNumber mult = trunc_input / KNumber(90);
596  if (mult.type() == KNumber::TYPE_INTEGER) {
597  if (mult == KNumber::Zero)
598  last_number_ = KNumber::Zero;
599  else if (mult == KNumber::One)
600  last_number_ = KNumber::One;
601  else if (mult == KNumber(2))
602  last_number_ = KNumber::Zero;
603  else if (mult == KNumber(3))
604  last_number_ = KNumber::NegOne;
605  else kDebug() << "Something wrong in CalcEngine::SinDeg";
606  return;
607  }
608  }
609  trunc_input = Deg2Rad(trunc_input);
610 
611  last_number_ = trunc_input.sin();
612 }
613 
614 void CalcEngine::SinRad(const KNumber &input)
615 {
616  if (input.type() == KNumber::TYPE_ERROR) {
617  last_number_ = KNumber::NaN;
618  return;
619  }
620 
621  last_number_ = input.sin();
622 }
623 
624 void CalcEngine::SinGrad(const KNumber &input)
625 {
626  if (input.type() == KNumber::TYPE_ERROR) {
627  last_number_ = KNumber::NaN;
628  return;
629  }
630 
631  KNumber trunc_input = moveIntoGradInterval(input);
632  if (trunc_input.type() == KNumber::TYPE_INTEGER) {
633  KNumber mult = trunc_input / KNumber(100);
634  if (mult.type() == KNumber::TYPE_INTEGER) {
635  if (mult == KNumber::Zero)
636  last_number_ = KNumber::Zero;
637  else if (mult == KNumber::One)
638  last_number_ = KNumber::One;
639  else if (mult == KNumber(2))
640  last_number_ = KNumber::Zero;
641  else if (mult == KNumber(3))
642  last_number_ = KNumber::NegOne;
643  else kDebug() << "Something wrong in CalcEngine::SinGrad";
644  return;
645  }
646  }
647 
648  trunc_input = Gra2Rad(trunc_input);
649 
650  last_number_ = trunc_input.sin();
651 }
652 
653 void CalcEngine::SinHyp(const KNumber &input)
654 {
655  if (input.type() == KNumber::TYPE_ERROR) {
656  if (input == KNumber::NaN) last_number_ = KNumber::NaN;
657  if (input == KNumber::PosInfinity) last_number_ = KNumber::PosInfinity;
658  if (input == KNumber::NegInfinity) last_number_ = KNumber::NegInfinity;
659  return;
660  }
661 
662  last_number_ = input.sinh();
663 }
664 
665 void CalcEngine::Square(const KNumber &input)
666 {
667  last_number_ = input * input;
668 }
669 
670 void CalcEngine::SquareRoot(const KNumber &input)
671 {
672  last_number_ = input.sqrt();
673 }
674 
675 void CalcEngine::StatClearAll(const KNumber &input)
676 {
677  Q_UNUSED(input);
678  stats.clearAll();
679 }
680 
681 void CalcEngine::StatCount(const KNumber &input)
682 {
683  Q_UNUSED(input);
684  last_number_ = KNumber(stats.count());
685 }
686 
687 void CalcEngine::StatDataNew(const KNumber &input)
688 {
689  stats.enterData(input);
690  last_number_ = KNumber(stats.count());
691 }
692 
693 void CalcEngine::StatDataDel(const KNumber &input)
694 {
695  Q_UNUSED(input);
696  stats.clearLast();
697  last_number_ = KNumber::Zero;
698 }
699 
700 void CalcEngine::StatMean(const KNumber &input)
701 {
702  Q_UNUSED(input);
703  last_number_ = stats.mean();
704 
705  error_ = stats.error();
706 }
707 
708 void CalcEngine::StatMedian(const KNumber &input)
709 {
710  Q_UNUSED(input);
711  last_number_ = stats.median();
712 
713  error_ = stats.error();
714 }
715 
716 void CalcEngine::StatStdDeviation(const KNumber &input)
717 {
718  Q_UNUSED(input);
719  last_number_ = stats.std();
720 
721  error_ = stats.error();
722 }
723 
724 void CalcEngine::StatStdSample(const KNumber &input)
725 {
726  Q_UNUSED(input);
727  last_number_ = stats.sample_std();
728 
729  error_ = stats.error();
730 }
731 
732 void CalcEngine::StatSum(const KNumber &input)
733 {
734  Q_UNUSED(input);
735  last_number_ = stats.sum();
736 }
737 
738 void CalcEngine::StatSumSquares(const KNumber &input)
739 {
740  Q_UNUSED(input);
741  last_number_ = stats.sum_of_squares();
742 
743  error_ = stats.error();
744 }
745 
746 void CalcEngine::TangensDeg(const KNumber &input)
747 {
748  if (input.type() == KNumber::TYPE_ERROR) {
749  last_number_ = KNumber::NaN;
750  return;
751  }
752 
753  SinDeg(input);
754  KNumber arg1 = last_number_;
755  CosDeg(input);
756  KNumber arg2 = last_number_;
757  last_number_ = arg1 / arg2;
758 }
759 
760 void CalcEngine::TangensRad(const KNumber &input)
761 {
762  if (input.type() == KNumber::TYPE_ERROR) {
763  last_number_ = KNumber::NaN;
764  return;
765  }
766 
767  SinRad(input);
768  KNumber arg1 = last_number_;
769  CosRad(input);
770  KNumber arg2 = last_number_;
771  last_number_ = arg1 / arg2;
772 }
773 
774 void CalcEngine::TangensGrad(const KNumber &input)
775 {
776  if (input.type() == KNumber::TYPE_ERROR) {
777  last_number_ = KNumber::NaN;
778  return;
779  }
780 
781  SinGrad(input);
782  KNumber arg1 = last_number_;
783  CosGrad(input);
784  KNumber arg2 = last_number_;
785  last_number_ = arg1 / arg2;
786 }
787 
788 void CalcEngine::TangensHyp(const KNumber &input)
789 {
790  if (input.type() == KNumber::TYPE_ERROR) {
791  if (input == KNumber::NaN) last_number_ = KNumber::NaN;
792  if (input == KNumber::PosInfinity) last_number_ = KNumber::One;
793  if (input == KNumber::NegInfinity) last_number_ = KNumber::NegOne;
794  return;
795  }
796 
797  last_number_ = input.tanh();
798 }
799 
800 KNumber CalcEngine::evalOperation(const KNumber &arg1, Operation operation, const KNumber &arg2)
801 {
802  if (!percent_mode_ || Operator[operation].prcnt_ptr == NULL) {
803  return (Operator[operation].arith_ptr)(arg1, arg2);
804  } else {
805  percent_mode_ = false;
806  return (Operator[operation].prcnt_ptr)(arg1, arg2);
807  }
808 }
809 
810 void CalcEngine::enterOperation(const KNumber &number, Operation func)
811 {
812  Node tmp_node;
813 
814  if (func == FUNC_BRACKET) {
815  tmp_node.number = KNumber::Zero;
816  tmp_node.operation = FUNC_BRACKET;
817 
818  stack_.push(tmp_node);
819 
820  return;
821  }
822 
823  if (func == FUNC_PERCENT) {
824  percent_mode_ = true;
825  }
826 
827  tmp_node.number = number;
828  tmp_node.operation = func;
829 
830  stack_.push(tmp_node);
831 
832  evalStack();
833 }
834 
835 bool CalcEngine::evalStack()
836 {
837  // this should never happen
838  Q_ASSERT(!stack_.isEmpty());
839 
840  Node tmp_node = stack_.pop();
841 
842  while (! stack_.isEmpty()) {
843  Node tmp_node2 = stack_.pop();
844  if (Operator[tmp_node.operation].precedence <=
845  Operator[tmp_node2.operation].precedence) {
846  if (tmp_node2.operation == FUNC_BRACKET) continue;
847  const KNumber tmp_result = evalOperation(tmp_node2.number, tmp_node2.operation, tmp_node.number);
848  tmp_node.number = tmp_result;
849  } else {
850  stack_.push(tmp_node2);
851  break;
852  }
853 
854  }
855 
856  if (tmp_node.operation != FUNC_EQUAL && tmp_node.operation != FUNC_PERCENT)
857  stack_.push(tmp_node);
858 
859  last_number_ = tmp_node.number;
860  return true;
861 }
862 
863 void CalcEngine::Reset()
864 {
865  error_ = false;
866  last_number_ = KNumber::Zero;
867 
868  stack_.clear();
869 }
870 
871 
CalcEngine::CosGrad
void CosGrad(const KNumber &input)
Definition: kcalc_core.cpp:443
CalcEngine::Square
void Square(const KNumber &input)
Definition: kcalc_core.cpp:665
CalcEngine::Complement
void Complement(const KNumber &input)
Definition: kcalc_core.cpp:394
CalcEngine::SquareRoot
void SquareRoot(const KNumber &input)
Definition: kcalc_core.cpp:670
KNumber::pow
KNumber pow(const KNumber &x) const
Definition: knumber.cpp:674
CalcEngine::AreaSinHyp
void AreaSinHyp(const KNumber &input)
Definition: kcalc_core.cpp:356
KStats::median
KNumber median()
Definition: stats.cpp:84
KNumber::NegInfinity
static const KNumber NegInfinity
Definition: knumber.h:54
CalcEngine::CosDeg
void CosDeg(const KNumber &input)
Definition: kcalc_core.cpp:404
CalcEngine::enterOperation
void enterOperation(const KNumber &num, Operation func)
Definition: kcalc_core.cpp:810
KNumber::asinh
KNumber asinh() const
Definition: knumber.cpp:785
KNumber::atan
KNumber atan() const
Definition: knumber.cpp:745
CalcEngine::StatSumSquares
void StatSumSquares(const KNumber &input)
Definition: kcalc_core.cpp:738
KNumber::NaN
static const KNumber NaN
Definition: knumber.h:55
KNumber::One
static const KNumber One
Definition: knumber.h:51
CalcEngine::TangensDeg
void TangensDeg(const KNumber &input)
Definition: kcalc_core.cpp:746
CalcEngine::Reset
void Reset()
Definition: kcalc_core.cpp:863
kcalc_core.h
KNumber::Zero
static const KNumber Zero
Definition: knumber.h:50
KNumber::acosh
KNumber acosh() const
Definition: knumber.cpp:795
KNumber::cos
KNumber cos() const
Definition: knumber.cpp:705
CalcEngine::Reciprocal
void Reciprocal(const KNumber &input)
Definition: kcalc_core.cpp:580
CalcEngine::TangensHyp
void TangensHyp(const KNumber &input)
Definition: kcalc_core.cpp:788
CalcEngine::CubeRoot
void CubeRoot(const KNumber &input)
Definition: kcalc_core.cpp:491
KStats::count
int count() const
Definition: stats.cpp:196
CalcEngine::ParenOpen
void ParenOpen(const KNumber &input)
Definition: kcalc_core.cpp:575
CalcEngine::Exp
void Exp(const KNumber &input)
Definition: kcalc_core.cpp:496
KNumber::TYPE_INTEGER
Definition: knumber.h:43
KStats::error
bool error()
Definition: stats.cpp:205
CalcEngine::SinRad
void SinRad(const KNumber &input)
Definition: kcalc_core.cpp:614
CalcEngine::StatMedian
void StatMedian(const KNumber &input)
Definition: kcalc_core.cpp:708
KNumber::Euler
static KNumber Euler()
Definition: knumber.cpp:255
KNumber::integerPart
KNumber integerPart() const
Definition: knumber.cpp:434
CalcEngine::TangensRad
void TangensRad(const KNumber &input)
Definition: kcalc_core.cpp:760
CalcEngine::StatMean
void StatMean(const KNumber &input)
Definition: kcalc_core.cpp:700
KNumber::bin
KNumber bin(const KNumber &x) const
Definition: knumber.cpp:892
CalcEngine::FUNC_PERCENT
Definition: kcalc_core.h:34
KStats::sample_std
KNumber sample_std()
Definition: stats.cpp:178
CalcEngine::Cube
void Cube(const KNumber &input)
Definition: kcalc_core.cpp:486
CalcEngine::SinHyp
void SinHyp(const KNumber &input)
Definition: kcalc_core.cpp:653
CalcEngine::StatStdSample
void StatStdSample(const KNumber &input)
Definition: kcalc_core.cpp:724
KStats::enterData
void enterData(const KNumber &data)
Definition: stats.cpp:50
CalcEngine::SinDeg
void SinDeg(const KNumber &input)
Definition: kcalc_core.cpp:586
KNumber::log10
KNumber log10() const
Definition: knumber.cpp:842
CalcEngine::ArcCosGrad
void ArcCosGrad(const KNumber &input)
Definition: kcalc_core.cpp:217
CalcEngine::ArcSinDeg
void ArcSinDeg(const KNumber &input)
Definition: kcalc_core.cpp:240
CalcEngine::ArcTangensDeg
void ArcTangensDeg(const KNumber &input)
Definition: kcalc_core.cpp:298
CalcEngine::ArcCosDeg
void ArcCosDeg(const KNumber &input)
Definition: kcalc_core.cpp:184
CalcEngine::SinGrad
void SinGrad(const KNumber &input)
Definition: kcalc_core.cpp:624
CalcEngine::CosHyp
void CosHyp(const KNumber &input)
Definition: kcalc_core.cpp:470
KNumber::type
Type type() const
Definition: knumber.cpp:400
CalcEngine::Operation
Operation
Definition: kcalc_core.h:32
KStats::sum
KNumber sum() const
Definition: stats.cpp:69
CalcEngine::AreaTangensHyp
void AreaTangensHyp(const KNumber &input)
Definition: kcalc_core.cpp:372
CalcEngine::FUNC_BRACKET
Definition: kcalc_core.h:35
CalcEngine::CosRad
void CosRad(const KNumber &input)
Definition: kcalc_core.cpp:433
CalcEngine::Log10
void Log10(const KNumber &input)
Definition: kcalc_core.cpp:549
CalcEngine::StatSum
void StatSum(const KNumber &input)
Definition: kcalc_core.cpp:732
CalcEngine::Factorial
void Factorial(const KNumber &input)
Definition: kcalc_core.cpp:519
CalcEngine::ArcSinGrad
void ArcSinGrad(const KNumber &input)
Definition: kcalc_core.cpp:274
CalcEngine::ArcSinRad
void ArcSinRad(const KNumber &input)
Definition: kcalc_core.cpp:264
CalcEngine::StatClearAll
void StatClearAll(const KNumber &input)
Definition: kcalc_core.cpp:675
KNumber
Definition: knumber.h:31
CalcEngine::AreaCosHyp
void AreaCosHyp(const KNumber &input)
Definition: kcalc_core.cpp:336
KNumber::sin
KNumber sin() const
Definition: knumber.cpp:695
KStats::clearLast
void clearLast()
Definition: stats.cpp:58
CalcEngine::TangensGrad
void TangensGrad(const KNumber &input)
Definition: kcalc_core.cpp:774
CalcEngine::lastOutput
KNumber lastOutput(bool &error) const
Definition: kcalc_core.cpp:179
CalcEngine::FUNC_EQUAL
Definition: kcalc_core.h:33
KNumber::cosh
KNumber cosh() const
Definition: knumber.cpp:765
KNumber::PosInfinity
static const KNumber PosInfinity
Definition: knumber.h:53
KNumber::cbrt
KNumber cbrt() const
Definition: knumber.cpp:654
KNumber::factorial
KNumber factorial() const
Definition: knumber.cpp:815
CalcEngine::StatDataDel
void StatDataDel(const KNumber &input)
Definition: kcalc_core.cpp:693
CalcEngine::ParenClose
void ParenClose(KNumber input)
Definition: kcalc_core.cpp:562
KNumber::Pi
static KNumber Pi()
Definition: knumber.cpp:240
CalcEngine::ArcCosRad
void ArcCosRad(const KNumber &input)
Definition: kcalc_core.cpp:208
CalcEngine::ArcTangensRad
void ArcTangensRad(const KNumber &input)
Definition: kcalc_core.cpp:310
KNumber::asin
KNumber asin() const
Definition: knumber.cpp:725
KNumber::ln
KNumber ln() const
Definition: knumber.cpp:852
KNumber::acos
KNumber acos() const
Definition: knumber.cpp:735
KNumber::atanh
KNumber atanh() const
Definition: knumber.cpp:805
CalcEngine::InvertSign
void InvertSign(const KNumber &input)
Definition: kcalc_core.cpp:531
CalcEngine::StatStdDeviation
void StatStdDeviation(const KNumber &input)
Definition: kcalc_core.cpp:716
CalcEngine::StatDataNew
void StatDataNew(const KNumber &input)
Definition: kcalc_core.cpp:687
KNumber::NegOne
static const KNumber NegOne
Definition: knumber.h:52
KStats::sum_of_squares
KNumber sum_of_squares() const
Definition: stats.cpp:135
KNumber::sinh
KNumber sinh() const
Definition: knumber.cpp:755
KNumber::sqrt
KNumber sqrt() const
Definition: knumber.cpp:664
CalcEngine::CalcEngine
CalcEngine()
Definition: kcalc_core.cpp:173
CalcEngine::Exp10
void Exp10(const KNumber &input)
Definition: kcalc_core.cpp:507
CalcEngine::StatCount
void StatCount(const KNumber &input)
Definition: kcalc_core.cpp:681
KNumber::TYPE_ERROR
Definition: knumber.h:42
KStats::mean
KNumber mean()
Definition: stats.cpp:150
CalcEngine::ArcTangensGrad
void ArcTangensGrad(const KNumber &input)
Definition: kcalc_core.cpp:324
KStats::std
KNumber std()
Definition: stats.cpp:164
KStats::clearAll
void clearAll()
Definition: stats.cpp:42
KNumber::tanh
KNumber tanh() const
Definition: knumber.cpp:775
CalcEngine::Ln
void Ln(const KNumber &input)
Definition: kcalc_core.cpp:536
This file is part of the KDE documentation.
Documentation copyright © 1996-2014 The KDE developers.
Generated on Tue Oct 14 2014 23:08:05 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

kcalc

Skip menu "kcalc"
  • Main Page
  • Namespace List
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members

kdeutils API Reference

Skip menu "kdeutils API Reference"
  • ark
  • filelight
  • kcalc
  • kcharselect
  • kdf
  • kfloppy
  • kgpg
  • kremotecontrol
  • ktimer
  • kwallet
  • superkaramba
  • sweeper

Search



Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal