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

kcalc

  • sources
  • kde-4.14
  • 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::Gamma(const KNumber &input)
532 {
533  if (input == KNumber::PosInfinity) return;
534  if (input < KNumber::Zero || input.type() == KNumber::TYPE_ERROR) {
535  error_ = true;
536  last_number_ = KNumber::NaN;
537  return;
538  }
539 
540  last_number_ = input.tgamma();
541 }
542 
543 void CalcEngine::InvertSign(const KNumber &input)
544 {
545  last_number_ = -input;
546 }
547 
548 void CalcEngine::Ln(const KNumber &input)
549 {
550  if (input < KNumber::Zero)
551  last_number_ = KNumber::NaN;
552  else if (input == KNumber::Zero)
553  last_number_ = KNumber::NegInfinity;
554  else if (input == KNumber::One)
555  last_number_ = KNumber::Zero;
556  else {
557  last_number_ = input.ln();
558  }
559 }
560 
561 void CalcEngine::Log10(const KNumber &input)
562 {
563  if (input < KNumber::Zero)
564  last_number_ = KNumber::NaN;
565  else if (input == KNumber::Zero)
566  last_number_ = KNumber::NegInfinity;
567  else if (input == KNumber::One)
568  last_number_ = KNumber::Zero;
569  else {
570  last_number_ = input.log10();
571  }
572 }
573 
574 void CalcEngine::ParenClose(KNumber input)
575 {
576  // evaluate stack until corresponding opening bracket
577  while (!stack_.isEmpty()) {
578  Node tmp_node = stack_.pop();
579  if (tmp_node.operation == FUNC_BRACKET)
580  break;
581  input = evalOperation(tmp_node.number, tmp_node.operation, input);
582  }
583  last_number_ = input;
584  return;
585 }
586 
587 void CalcEngine::ParenOpen(const KNumber &input)
588 {
589  enterOperation(input, FUNC_BRACKET);
590 }
591 
592 void CalcEngine::Reciprocal(const KNumber &input)
593 {
594  last_number_ = KNumber::One / input;
595 }
596 
597 
598 void CalcEngine::SinDeg(const KNumber &input)
599 {
600  if (input.type() == KNumber::TYPE_ERROR) {
601  last_number_ = KNumber::NaN;
602  return;
603  }
604 
605  KNumber trunc_input = moveIntoDegInterval(input);
606  if (trunc_input.type() == KNumber::TYPE_INTEGER) {
607  KNumber mult = trunc_input / KNumber(90);
608  if (mult.type() == KNumber::TYPE_INTEGER) {
609  if (mult == KNumber::Zero)
610  last_number_ = KNumber::Zero;
611  else if (mult == KNumber::One)
612  last_number_ = KNumber::One;
613  else if (mult == KNumber(2))
614  last_number_ = KNumber::Zero;
615  else if (mult == KNumber(3))
616  last_number_ = KNumber::NegOne;
617  else kDebug() << "Something wrong in CalcEngine::SinDeg";
618  return;
619  }
620  }
621  trunc_input = Deg2Rad(trunc_input);
622 
623  last_number_ = trunc_input.sin();
624 }
625 
626 void CalcEngine::SinRad(const KNumber &input)
627 {
628  if (input.type() == KNumber::TYPE_ERROR) {
629  last_number_ = KNumber::NaN;
630  return;
631  }
632 
633  last_number_ = input.sin();
634 }
635 
636 void CalcEngine::SinGrad(const KNumber &input)
637 {
638  if (input.type() == KNumber::TYPE_ERROR) {
639  last_number_ = KNumber::NaN;
640  return;
641  }
642 
643  KNumber trunc_input = moveIntoGradInterval(input);
644  if (trunc_input.type() == KNumber::TYPE_INTEGER) {
645  KNumber mult = trunc_input / KNumber(100);
646  if (mult.type() == KNumber::TYPE_INTEGER) {
647  if (mult == KNumber::Zero)
648  last_number_ = KNumber::Zero;
649  else if (mult == KNumber::One)
650  last_number_ = KNumber::One;
651  else if (mult == KNumber(2))
652  last_number_ = KNumber::Zero;
653  else if (mult == KNumber(3))
654  last_number_ = KNumber::NegOne;
655  else kDebug() << "Something wrong in CalcEngine::SinGrad";
656  return;
657  }
658  }
659 
660  trunc_input = Gra2Rad(trunc_input);
661 
662  last_number_ = trunc_input.sin();
663 }
664 
665 void CalcEngine::SinHyp(const KNumber &input)
666 {
667  if (input.type() == KNumber::TYPE_ERROR) {
668  if (input == KNumber::NaN) last_number_ = KNumber::NaN;
669  if (input == KNumber::PosInfinity) last_number_ = KNumber::PosInfinity;
670  if (input == KNumber::NegInfinity) last_number_ = KNumber::NegInfinity;
671  return;
672  }
673 
674  last_number_ = input.sinh();
675 }
676 
677 void CalcEngine::Square(const KNumber &input)
678 {
679  last_number_ = input * input;
680 }
681 
682 void CalcEngine::SquareRoot(const KNumber &input)
683 {
684  last_number_ = input.sqrt();
685 }
686 
687 void CalcEngine::StatClearAll(const KNumber &input)
688 {
689  Q_UNUSED(input);
690  stats.clearAll();
691 }
692 
693 void CalcEngine::StatCount(const KNumber &input)
694 {
695  Q_UNUSED(input);
696  last_number_ = KNumber(stats.count());
697 }
698 
699 void CalcEngine::StatDataNew(const KNumber &input)
700 {
701  stats.enterData(input);
702  last_number_ = KNumber(stats.count());
703 }
704 
705 void CalcEngine::StatDataDel(const KNumber &input)
706 {
707  Q_UNUSED(input);
708  stats.clearLast();
709  last_number_ = KNumber(stats.count());
710 }
711 
712 void CalcEngine::StatMean(const KNumber &input)
713 {
714  Q_UNUSED(input);
715  last_number_ = stats.mean();
716 
717  error_ = stats.error();
718 }
719 
720 void CalcEngine::StatMedian(const KNumber &input)
721 {
722  Q_UNUSED(input);
723  last_number_ = stats.median();
724 
725  error_ = stats.error();
726 }
727 
728 void CalcEngine::StatStdDeviation(const KNumber &input)
729 {
730  Q_UNUSED(input);
731  last_number_ = stats.std();
732 
733  error_ = stats.error();
734 }
735 
736 void CalcEngine::StatStdSample(const KNumber &input)
737 {
738  Q_UNUSED(input);
739  last_number_ = stats.sample_std();
740 
741  error_ = stats.error();
742 }
743 
744 void CalcEngine::StatSum(const KNumber &input)
745 {
746  Q_UNUSED(input);
747  last_number_ = stats.sum();
748 }
749 
750 void CalcEngine::StatSumSquares(const KNumber &input)
751 {
752  Q_UNUSED(input);
753  last_number_ = stats.sum_of_squares();
754 
755  error_ = stats.error();
756 }
757 
758 void CalcEngine::TangensDeg(const KNumber &input)
759 {
760  if (input.type() == KNumber::TYPE_ERROR) {
761  last_number_ = KNumber::NaN;
762  return;
763  }
764 
765  SinDeg(input);
766  KNumber arg1 = last_number_;
767  CosDeg(input);
768  KNumber arg2 = last_number_;
769 
770  last_number_ = arg1 / arg2;
771 }
772 
773 void CalcEngine::TangensRad(const KNumber &input)
774 {
775  if (input.type() == KNumber::TYPE_ERROR) {
776  last_number_ = KNumber::NaN;
777  return;
778  }
779 
780  SinRad(input);
781  KNumber arg1 = last_number_;
782  CosRad(input);
783  KNumber arg2 = last_number_;
784 
785  last_number_ = arg1 / arg2;
786 }
787 
788 void CalcEngine::TangensGrad(const KNumber &input)
789 {
790  if (input.type() == KNumber::TYPE_ERROR) {
791  last_number_ = KNumber::NaN;
792  return;
793  }
794 
795  SinGrad(input);
796  KNumber arg1 = last_number_;
797  CosGrad(input);
798  KNumber arg2 = last_number_;
799 
800  last_number_ = arg1 / arg2;
801 }
802 
803 void CalcEngine::TangensHyp(const KNumber &input)
804 {
805  if (input.type() == KNumber::TYPE_ERROR) {
806  if (input == KNumber::NaN) last_number_ = KNumber::NaN;
807  if (input == KNumber::PosInfinity) last_number_ = KNumber::One;
808  if (input == KNumber::NegInfinity) last_number_ = KNumber::NegOne;
809  return;
810  }
811 
812  last_number_ = input.tanh();
813 }
814 
815 KNumber CalcEngine::evalOperation(const KNumber &arg1, Operation operation, const KNumber &arg2)
816 {
817  if (!percent_mode_ || Operator[operation].prcnt_ptr == NULL) {
818  return (Operator[operation].arith_ptr)(arg1, arg2);
819  } else {
820  percent_mode_ = false;
821  return (Operator[operation].prcnt_ptr)(arg1, arg2);
822  }
823 }
824 
825 void CalcEngine::enterOperation(const KNumber &number, Operation func)
826 {
827  Node tmp_node;
828 
829  if (func == FUNC_BRACKET) {
830  tmp_node.number = KNumber::Zero;
831  tmp_node.operation = FUNC_BRACKET;
832 
833  stack_.push(tmp_node);
834 
835  return;
836  }
837 
838  if (func == FUNC_PERCENT) {
839  percent_mode_ = true;
840  }
841 
842  tmp_node.number = number;
843  tmp_node.operation = func;
844 
845  stack_.push(tmp_node);
846 
847  evalStack();
848 }
849 
850 bool CalcEngine::evalStack()
851 {
852  // this should never happen
853  Q_ASSERT(!stack_.isEmpty());
854 
855  Node tmp_node = stack_.pop();
856 
857  while (! stack_.isEmpty()) {
858  Node tmp_node2 = stack_.pop();
859  if (Operator[tmp_node.operation].precedence <=
860  Operator[tmp_node2.operation].precedence) {
861  if (tmp_node2.operation == FUNC_BRACKET) continue;
862  const KNumber tmp_result = evalOperation(tmp_node2.number, tmp_node2.operation, tmp_node.number);
863  tmp_node.number = tmp_result;
864  } else {
865  stack_.push(tmp_node2);
866  break;
867  }
868 
869  }
870 
871  if (tmp_node.operation != FUNC_EQUAL && tmp_node.operation != FUNC_PERCENT)
872  stack_.push(tmp_node);
873 
874  last_number_ = tmp_node.number;
875  return true;
876 }
877 
878 void CalcEngine::Reset()
879 {
880  error_ = false;
881  last_number_ = KNumber::Zero;
882 
883  stack_.clear();
884 }
885 
886 
CalcEngine::CosGrad
void CosGrad(const KNumber &input)
Definition: kcalc_core.cpp:443
CalcEngine::Square
void Square(const KNumber &input)
Definition: kcalc_core.cpp:677
CalcEngine::Complement
void Complement(const KNumber &input)
Definition: kcalc_core.cpp:394
CalcEngine::SquareRoot
void SquareRoot(const KNumber &input)
Definition: kcalc_core.cpp:682
KNumber::pow
KNumber pow(const KNumber &x) const
Definition: knumber.cpp:682
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:53
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:825
KNumber::asinh
KNumber asinh() const
Definition: knumber.cpp:814
KNumber::atan
KNumber atan() const
Definition: knumber.cpp:774
CalcEngine::StatSumSquares
void StatSumSquares(const KNumber &input)
Definition: kcalc_core.cpp:750
QStack::pop
T pop()
KNumber::NaN
static const KNumber NaN
Definition: knumber.h:54
KNumber::One
static const KNumber One
Definition: knumber.h:50
CalcEngine::TangensDeg
void TangensDeg(const KNumber &input)
Definition: kcalc_core.cpp:758
CalcEngine::Reset
void Reset()
Definition: kcalc_core.cpp:878
kcalc_core.h
KNumber::Zero
static const KNumber Zero
Definition: knumber.h:49
KNumber::acosh
KNumber acosh() const
Definition: knumber.cpp:824
KNumber::cos
KNumber cos() const
Definition: knumber.cpp:721
QStack::push
void push(const T &t)
CalcEngine::Reciprocal
void Reciprocal(const KNumber &input)
Definition: kcalc_core.cpp:592
CalcEngine::TangensHyp
void TangensHyp(const KNumber &input)
Definition: kcalc_core.cpp:803
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:587
CalcEngine::Exp
void Exp(const KNumber &input)
Definition: kcalc_core.cpp:496
KNumber::TYPE_INTEGER
Definition: knumber.h:42
KStats::error
bool error()
Definition: stats.cpp:205
CalcEngine::SinRad
void SinRad(const KNumber &input)
Definition: kcalc_core.cpp:626
CalcEngine::StatMedian
void StatMedian(const KNumber &input)
Definition: kcalc_core.cpp:720
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:773
CalcEngine::StatMean
void StatMean(const KNumber &input)
Definition: kcalc_core.cpp:712
KNumber::bin
KNumber bin(const KNumber &x) const
Definition: knumber.cpp:941
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:665
CalcEngine::StatStdSample
void StatStdSample(const KNumber &input)
Definition: kcalc_core.cpp:736
KStats::enterData
void enterData(const KNumber &data)
Definition: stats.cpp:50
CalcEngine::SinDeg
void SinDeg(const KNumber &input)
Definition: kcalc_core.cpp:598
KNumber::log10
KNumber log10() const
Definition: knumber.cpp:871
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:636
CalcEngine::CosHyp
void CosHyp(const KNumber &input)
Definition: kcalc_core.cpp:470
KNumber::tgamma
KNumber tgamma() const
Definition: knumber.cpp:741
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:561
CalcEngine::StatSum
void StatSum(const KNumber &input)
Definition: kcalc_core.cpp:744
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:687
KNumber
Definition: knumber.h:30
CalcEngine::AreaCosHyp
void AreaCosHyp(const KNumber &input)
Definition: kcalc_core.cpp:336
KNumber::sin
KNumber sin() const
Definition: knumber.cpp:711
KStats::clearLast
void clearLast()
Definition: stats.cpp:58
CalcEngine::TangensGrad
void TangensGrad(const KNumber &input)
Definition: kcalc_core.cpp:788
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:794
KNumber::PosInfinity
static const KNumber PosInfinity
Definition: knumber.h:52
KNumber::cbrt
KNumber cbrt() const
Definition: knumber.cpp:662
KNumber::factorial
KNumber factorial() const
Definition: knumber.cpp:844
CalcEngine::StatDataDel
void StatDataDel(const KNumber &input)
Definition: kcalc_core.cpp:705
CalcEngine::ParenClose
void ParenClose(KNumber input)
Definition: kcalc_core.cpp:574
CalcEngine::Gamma
void Gamma(const KNumber &input)
Definition: kcalc_core.cpp:531
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:754
KNumber::ln
KNumber ln() const
Definition: knumber.cpp:881
KNumber::acos
KNumber acos() const
Definition: knumber.cpp:764
KNumber::atanh
KNumber atanh() const
Definition: knumber.cpp:834
CalcEngine::InvertSign
void InvertSign(const KNumber &input)
Definition: kcalc_core.cpp:543
CalcEngine::StatStdDeviation
void StatStdDeviation(const KNumber &input)
Definition: kcalc_core.cpp:728
CalcEngine::StatDataNew
void StatDataNew(const KNumber &input)
Definition: kcalc_core.cpp:699
KNumber::NegOne
static const KNumber NegOne
Definition: knumber.h:51
KStats::sum_of_squares
KNumber sum_of_squares() const
Definition: stats.cpp:135
KNumber::sinh
KNumber sinh() const
Definition: knumber.cpp:784
KNumber::sqrt
KNumber sqrt() const
Definition: knumber.cpp:672
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:693
KNumber::TYPE_ERROR
Definition: knumber.h:41
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:804
CalcEngine::Ln
void Ln(const KNumber &input)
Definition: kcalc_core.cpp:548
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Mon Jun 22 2020 13:42:28 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
  • ktimer
  • kwallet
  • 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