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

kcalc

kcalc_core.cpp

Go to the documentation of this file.
00001 /*
00002     kCalculator, a scientific calculator for the X window system using the
00003     Qt widget libraries, available at no cost at http://www.troll.no
00004 
00005     The stack engine contained in this file was take from
00006     Martin Bartlett's xfrmcalc
00007 
00008     portions:   Copyright (C) 2003-2006 Klaus Niederkrueger
00009                                         kniederk@ulb.ac.be
00010 
00011     portions:   Copyright (C) 1996 Bernd Johannes Wuebben
00012                                    wuebben@math.cornell.edu
00013 
00014     portions:   Copyright (C) 1995 Martin Bartlett
00015 
00016     This program is free software; you can redistribute it and/or modify
00017     it under the terms of the GNU General Public License as published by
00018     the Free Software Foundation; either version 2 of the License, or
00019     (at your option) any later version.
00020 
00021     This program is distributed in the hope that it will be useful,
00022     but WITHOUT ANY WARRANTY; without even the implied warranty of
00023     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00024     GNU General Public License for more details.
00025 
00026     You should have received a copy of the GNU General Public License
00027     along with this program; if not, write to the Free Software
00028     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
00029 
00030 */
00031 
00032 #include <config-kcalc.h>
00033 
00034 #if defined(_ISOC99_SOURCE)
00035     #include <cassert>
00036     #include <cstdio>
00037     #include <climits>
00038     #include <csignal>
00039     #include <cerrno>
00040     #include <cstring>
00041     using namespace std;
00042 #else
00043     #include <limits.h>
00044     #include <stdio.h>
00045     #include <assert.h> 
00046     #include <signal.h>
00047     #include <errno.h>
00048     #include <string.h>
00049 #endif
00050 
00051 #include "kcalc_core.h"
00052 #include <stdlib.h>
00053 #include <klocale.h>
00054 #include <kmessagebox.h>
00055 #include "kcalctype.h"
00056 
00057 #ifndef HAVE_FUNC_ISINF
00058         #ifdef HAVE_IEEEFP_H
00059                 #include <ieeefp.h>
00060         #else
00061                 #include <math.h>
00062         #endif
00063 
00064 #undef isinf
00065 int isinf(double x) 
00066 {
00067 #ifdef _HPUX_SOURCE
00068 return !isfinite(x) && x == x;
00069 #else
00070 return !finite(x) && x==x; 
00071 #endif
00072 }
00073 
00074 #endif
00075 
00076 
00077 static void fpe_handler(int fpe_parm)
00078 {
00079     UNUSED(fpe_parm);
00080     //  display_error = true;
00081     //tmp_number = 0L;
00082 }
00083 
00084 
00085 static bool _error;
00086 
00087 static KNumber ExecOr(const KNumber & left_op, const KNumber & right_op)
00088 {
00089     return (left_op | right_op);
00090 }
00091 
00092 static KNumber ExecXor(const KNumber & left_op, const KNumber & right_op)
00093 {
00094     return (left_op | right_op) - (left_op & right_op);
00095 }
00096 
00097 static KNumber ExecAnd(const KNumber & left_op, const KNumber & right_op)
00098 {
00099     return (left_op & right_op);
00100 }
00101 
00102 static KNumber ExecLsh(const KNumber & left_op, const KNumber & right_op)
00103 {
00104     return left_op << right_op;
00105 }
00106 
00107 static KNumber ExecRsh(const KNumber & left_op, const KNumber & right_op)
00108 {
00109     return left_op >> right_op;
00110 }
00111 
00112 static KNumber ExecAdd(const KNumber & left_op, const KNumber & right_op)
00113 {
00114     return left_op + right_op;
00115 }
00116 
00117 static KNumber ExecSubtract(const KNumber & left_op, const KNumber & right_op)
00118 {
00119     return left_op - right_op;
00120 }
00121 
00122 static KNumber ExecMultiply(const KNumber & left_op, const KNumber & right_op)
00123 {
00124     return left_op * right_op;
00125 }
00126 
00127 static KNumber ExecDivide(const KNumber & left_op, const KNumber & right_op)
00128 {
00129     return left_op / right_op;
00130 }
00131 
00132 static KNumber ExecMod(const KNumber & left_op, const KNumber & right_op)
00133 {
00134     return left_op % right_op;
00135 }
00136 
00137 static KNumber ExecIntDiv(const KNumber & left_op, const KNumber & right_op)
00138 {
00139     return (left_op / right_op).integerPart();
00140 }
00141 
00142 bool isoddint(const KNumber & input)
00143 {
00144     if (input.type() != KNumber::IntegerType) return false;
00145     // Routine to check if KNumber is an Odd integer
00146     return ( (input / KNumber(2)).type() == KNumber::IntegerType);
00147 }
00148 
00149   
00150 static KNumber ExecBinom(const KNumber & left_op, const KNumber & right_op) 
00151 { 
00152     if (left_op.type() != KNumber::IntegerType
00153         ||  right_op.type() != KNumber::IntegerType
00154         ||  right_op > left_op  ||  left_op < KNumber::Zero)
00155         return KNumber::UndefinedNumber;
00156 
00157     KNumber tmp_count = left_op;
00158     KNumber tmp_result = KNumber::One;
00159 
00160     // don't do recursive factorial,
00161     // because large numbers lead to
00162     // stack overflows
00163     while (tmp_count > right_op)
00164     {
00165         tmp_result = tmp_count * tmp_result;
00166         tmp_count -= KNumber::One;
00167     }
00168 
00169     tmp_count = left_op-right_op;
00170     while (tmp_count > KNumber::One)
00171     {
00172         tmp_result = tmp_result / tmp_count;
00173         tmp_count -= KNumber::One;
00174     }
00175 
00176 
00177     return tmp_result;
00178 } 
00179 
00180 static KNumber ExecPower(const KNumber & left_op, const KNumber & right_op)
00181 {
00182     return left_op.power(right_op);
00183 }
00184 
00185 static KNumber ExecPwrRoot(const KNumber & left_op, const KNumber & right_op)
00186 {
00187     return left_op.power(KNumber::One / right_op);
00188 }
00189 
00190 static KNumber ExecAddP(const KNumber & left_op, const KNumber & right_op)
00191 {
00192     return left_op * (KNumber::One + right_op/KNumber(100));
00193 }
00194 
00195 static KNumber ExecSubP(const KNumber & left_op, const KNumber & right_op)
00196 {
00197     return left_op * (KNumber::One - right_op/KNumber(100));
00198 }
00199 
00200 static KNumber ExecMultiplyP(const KNumber & left_op, const KNumber & right_op)
00201 {
00202     return left_op * right_op / KNumber(100);
00203 }
00204 
00205 static KNumber ExecDivideP(const KNumber & left_op, const KNumber & right_op)
00206 {
00207     return left_op * KNumber(100) / right_op;
00208 }
00209 
00210 
00211 // build precedence list
00212 const struct operator_data CalcEngine::Operator[] = {
00213   { 0, NULL,     NULL}, // FUNC_EQUAL
00214   { 0, NULL,     NULL}, // FUNC_PERCENT
00215   { 0, NULL,     NULL}, // FUNC_BRACKET
00216   { 1, ExecOr,   NULL}, // FUNC_OR
00217   { 2, ExecXor,  NULL}, // FUNC_XOR
00218   { 3, ExecAnd,  NULL}, // FUNC_AND
00219   { 4, ExecLsh,  NULL}, // FUNC_LSH
00220   { 4, ExecRsh,  NULL}, // FUNC_RSH
00221   { 5, ExecAdd,  ExecAddP}, // FUNC_ADD
00222   { 5, ExecSubtract, ExecSubP}, // FUNC_SUBTRACT
00223   { 6, ExecMultiply, ExecMultiplyP}, // FUNC_MULTIPLY
00224   { 6, ExecDivide,   ExecDivideP}, // FUNC_DIVIDE
00225   { 6, ExecMod,  NULL}, // FUNC_MOD
00226   { 6, ExecIntDiv, NULL}, // FUNC_INTDIV
00227   { 7, ExecBinom, NULL},  // FUNC_BINOM 
00228   { 7, ExecPower,  NULL}, // FUNC_POWER
00229   { 7, ExecPwrRoot, NULL} // FUNC_PWR_ROOT
00230 };
00231 
00232 
00233 CalcEngine::CalcEngine()
00234   :   _percent_mode(false)
00235 {
00236     //
00237     // Basic initialization involves initializing the calcultion
00238     // stack, and setting up the floating point excetion signal
00239     // handler to trap the errors that the code can/has not been
00240     // written to trap.
00241     //
00242 
00243     struct sigaction fpe_trap;
00244 
00245     sigemptyset(&fpe_trap.sa_mask);
00246     fpe_trap.sa_handler = &fpe_handler;
00247 #ifdef SA_RESTART
00248     fpe_trap.sa_flags = SA_RESTART;
00249 #endif
00250     sigaction(SIGFPE, &fpe_trap, NULL);
00251 
00252     _last_number = KNumber::Zero;
00253     _error = false;
00254 }
00255 
00256 KNumber CalcEngine::lastOutput(bool &error) const
00257 {
00258     error = _error;
00259     return _last_number;
00260 }
00261 
00262 void CalcEngine::ArcCosDeg(KNumber input)
00263 {
00264     if (input.type() == KNumber::SpecialType  ||
00265         input < -KNumber::One  ||  input > KNumber::One) {
00266         _last_number = KNumber("nan");
00267         return;
00268     }
00269 
00270     if (input.type() == KNumber::IntegerType) {
00271         if (input == KNumber::One) {
00272           _last_number = KNumber::Zero;
00273             return;
00274         }
00275         if (input == - KNumber::One) {
00276             _last_number = KNumber(180);
00277             return;
00278         }
00279         if (input == KNumber::Zero) {
00280             _last_number = KNumber(90);
00281             return;
00282         }
00283     }
00284     CALCAMNT tmp_num = static_cast<double>(input);
00285     _last_number = Rad2Deg(KNumber(double(ACOS(tmp_num))));
00286 }
00287 
00288 void CalcEngine::ArcCosRad(KNumber input)
00289 {
00290     if (input.type() == KNumber::SpecialType  ||
00291         input < -KNumber::One  ||  input > KNumber::One) {
00292         _last_number = KNumber("nan");
00293         return;
00294     }
00295     CALCAMNT tmp_num = static_cast<double>(input);
00296     _last_number = KNumber(double(ACOS(tmp_num)));
00297 }
00298 
00299 void CalcEngine::ArcCosGrad(KNumber input)
00300 {
00301     if (input.type() == KNumber::SpecialType  ||
00302         input < -KNumber::One  ||  input > KNumber::One) {
00303         _last_number = KNumber("nan");
00304         return;
00305     }
00306     if (input.type() == KNumber::IntegerType) {
00307         if (input == KNumber::One) {
00308             _last_number = KNumber::Zero;
00309             return;
00310         }
00311         if (input == - KNumber::One) {
00312             _last_number = KNumber(200);
00313             return;
00314         }
00315         if (input == KNumber::Zero) {
00316             _last_number = KNumber(100);
00317             return;
00318         }
00319     }
00320     CALCAMNT tmp_num = static_cast<double>(input);
00321     _last_number = Rad2Gra(KNumber(double(ACOS(tmp_num))));
00322 }
00323 
00324 void CalcEngine::ArcSinDeg(KNumber input)
00325 {
00326     if (input.type() == KNumber::SpecialType  ||
00327         input < -KNumber::One  ||  input > KNumber::One) {
00328         _last_number = KNumber("nan");
00329         return;
00330     }
00331     if (input.type() == KNumber::IntegerType) {
00332         if (input == KNumber::One) {
00333             _last_number = KNumber(90);
00334             return;
00335         }
00336         if (input == - KNumber::One) {
00337             _last_number = KNumber(-90);
00338             return;
00339         }
00340         if (input == KNumber::Zero) {
00341             _last_number = KNumber(0);
00342             return;
00343         }
00344     }
00345     CALCAMNT tmp_num = static_cast<double>(input);
00346     _last_number = Rad2Deg(KNumber(double(ASIN(tmp_num))));
00347 }
00348 
00349 void CalcEngine::ArcSinRad(KNumber input)
00350 {
00351     if (input.type() == KNumber::SpecialType  ||
00352         input < -KNumber::One  ||  input > KNumber::One) {
00353         _last_number = KNumber("nan");
00354         return;
00355     }
00356     CALCAMNT tmp_num = static_cast<double>(input);
00357     _last_number = KNumber(double(ASIN(tmp_num)));
00358 }
00359 
00360 void CalcEngine::ArcSinGrad(KNumber input)
00361 {
00362     if (input.type() == KNumber::SpecialType  ||
00363         input < -KNumber::One  ||  input > KNumber::One) {
00364         _last_number = KNumber("nan");
00365         return;
00366     }
00367     if (input.type() == KNumber::IntegerType) {
00368         if (input == KNumber::One) {
00369             _last_number = KNumber(100);
00370             return;
00371         }
00372         if (input == - KNumber::One) {
00373             _last_number = KNumber(-100);
00374             return;
00375         }
00376         if (input == KNumber::Zero) {
00377             _last_number = KNumber(0);
00378             return;
00379         }
00380     }
00381     CALCAMNT tmp_num = static_cast<double>(input);
00382     _last_number = Rad2Gra(KNumber(double(ASIN(tmp_num))));
00383 }
00384 
00385 void CalcEngine::ArcTangensDeg(KNumber input)
00386 {
00387     if (input.type() == KNumber::SpecialType) {
00388         if (input == KNumber("nan")) _last_number = KNumber("nan");
00389         if (input == KNumber("inf")) _last_number = KNumber(90);
00390         if (input == KNumber("-inf"))  _last_number = KNumber(-90);
00391         return;
00392     }
00393 
00394     CALCAMNT tmp_num = static_cast<double>(input);
00395     _last_number = Rad2Deg(KNumber(double(ATAN(tmp_num))));
00396 }
00397 
00398 void CalcEngine::ArcTangensRad(KNumber input)
00399 {
00400     if (input.type() == KNumber::SpecialType) {
00401         if (input == KNumber("nan")) _last_number = KNumber("nan");
00402         if (input == KNumber("inf"))
00403             _last_number = KNumber::Pi/KNumber(2);
00404         if (input == KNumber("-inf"))
00405             _last_number = -KNumber::Pi/KNumber(2);
00406         return;
00407     }
00408 
00409     CALCAMNT tmp_num = static_cast<double>(input);
00410     _last_number = KNumber(double(ATAN(tmp_num)));
00411 }
00412 
00413 void CalcEngine::ArcTangensGrad(KNumber input)
00414 {
00415     if (input.type() == KNumber::SpecialType) {
00416         if (input == KNumber("nan")) _last_number = KNumber("nan");
00417         if (input == KNumber("inf")) _last_number = KNumber(100);
00418         if (input == KNumber("-inf"))  _last_number = KNumber(-100);
00419         return;
00420     }
00421 
00422     CALCAMNT tmp_num = static_cast<double>(input);
00423     _last_number = Rad2Gra(KNumber(double(ATAN(tmp_num))));
00424 }
00425 
00426 void CalcEngine::AreaCosHyp(KNumber input)
00427 {
00428     if (input.type() == KNumber::SpecialType) {
00429         if (input == KNumber("nan")) _last_number = KNumber("nan");
00430         if (input == KNumber("inf")) _last_number = KNumber("inf");
00431         if (input == KNumber("-inf"))  _last_number = KNumber("nan");
00432         return;
00433     }
00434 
00435     if (input < KNumber::One) {
00436       _last_number = KNumber("nan");
00437       return;
00438     }
00439     if (input == KNumber::One) {
00440       _last_number = KNumber::Zero;
00441       return;
00442     }
00443     CALCAMNT tmp_num = static_cast<double>(input);
00444     _last_number = KNumber(double(ACOSH(tmp_num)));
00445 }
00446 
00447 void CalcEngine::AreaSinHyp(KNumber input)
00448 {
00449     if (input.type() == KNumber::SpecialType) {
00450         if (input == KNumber("nan")) _last_number = KNumber("nan");
00451         if (input == KNumber("inf")) _last_number = KNumber("inf");
00452         if (input == KNumber("-inf"))  _last_number = KNumber("-inf");
00453         return;
00454     }
00455 
00456     if (input == KNumber::Zero) {
00457       _last_number = KNumber::Zero;
00458       return;
00459     }
00460     CALCAMNT tmp_num = static_cast<double>(input);
00461     _last_number = KNumber(double(ASINH(tmp_num)));
00462 }
00463 
00464 void CalcEngine::AreaTangensHyp(KNumber input)
00465 {
00466     if (input.type() == KNumber::SpecialType) {
00467         _last_number = KNumber("nan");
00468         return;
00469     }
00470 
00471     if (input < -KNumber::One  ||  input > KNumber::One) {
00472         _last_number = KNumber("nan");
00473         return;
00474     }
00475     if (input == KNumber::One) {
00476         _last_number = KNumber("inf");
00477         return;
00478     }
00479     if (input == - KNumber::One) {
00480         _last_number = KNumber("-inf");
00481         return;
00482     }
00483     CALCAMNT tmp_num = static_cast<double>(input);
00484     _last_number = KNumber(double(ATANH(tmp_num)));
00485 }
00486 
00487 void CalcEngine::Complement(KNumber input)
00488 {
00489     if (input.type() != KNumber::IntegerType)
00490     {
00491         _last_number = KNumber("nan");
00492         return;
00493     }
00494     _last_number = - input - KNumber::One;
00495 }
00496 
00497 
00498 
00499 // move a number into the interval [0,360) by adding multiples of 360
00500 static KNumber const moveIntoDegInterval(KNumber const &num)
00501 {
00502     KNumber tmp_num = num - (num/KNumber(360)).integerPart() * KNumber(360);
00503     if(tmp_num < KNumber::Zero)
00504         return tmp_num + KNumber(360);
00505     return tmp_num;
00506 }
00507 
00508 // move a number into the interval [0,400) by adding multiples of 400
00509 static KNumber const moveIntoGradInterval(KNumber const &num)
00510 {
00511     KNumber tmp_num = num - (num/KNumber(400)).integerPart() * KNumber(400);
00512     if(tmp_num < KNumber::Zero)
00513         return tmp_num + KNumber(400);
00514     return tmp_num;
00515 }
00516 
00517 
00518 void CalcEngine::CosDeg(KNumber input)
00519 {
00520     if (input.type() == KNumber::SpecialType) {
00521         _last_number = KNumber("nan");
00522         return;
00523     }
00524     KNumber trunc_input = moveIntoDegInterval(input);
00525     if (trunc_input.type() == KNumber::IntegerType) {
00526         KNumber mult = trunc_input/KNumber(90);
00527         if (mult.type() == KNumber::IntegerType) {
00528           if (mult == KNumber::Zero)
00529             _last_number = 1;
00530           else if (mult == KNumber(1))
00531             _last_number = 0;
00532           else if (mult == KNumber(2))
00533             _last_number = -1;
00534           else if (mult == KNumber(3))
00535             _last_number = 0;
00536           else qDebug("Something wrong in CalcEngine::CosDeg\n");
00537           return;
00538         }
00539     }
00540     trunc_input = Deg2Rad(trunc_input);
00541 
00542     CALCAMNT tmp_num = static_cast<double>(trunc_input);
00543     _last_number = KNumber(double(COS(tmp_num)));
00544 }
00545 
00546 void CalcEngine::CosRad(KNumber input)
00547 {
00548     if (input.type() == KNumber::SpecialType) {
00549         _last_number = KNumber("nan");
00550         return;
00551     }
00552     CALCAMNT tmp_num = static_cast<double>(input);
00553     _last_number = KNumber(double(COS(tmp_num)));
00554 }
00555 
00556 void CalcEngine::CosGrad(KNumber input)
00557 {
00558     if (input.type() == KNumber::SpecialType) {
00559         _last_number = KNumber("nan");
00560         return;
00561     }
00562     KNumber trunc_input = moveIntoGradInterval(input);
00563     if (trunc_input.type() == KNumber::IntegerType) {
00564         KNumber mult = trunc_input/KNumber(100);
00565         if (mult.type() == KNumber::IntegerType) {
00566           if (mult == KNumber::Zero)
00567             _last_number = 1;
00568           else if (mult == KNumber(1))
00569             _last_number = 0;
00570           else if (mult == KNumber(2))
00571             _last_number = -1;
00572           else if (mult == KNumber(3))
00573             _last_number = 0;
00574           else qDebug("Something wrong in CalcEngine::CosGrad\n");
00575           return;
00576         }
00577     }
00578     trunc_input = Gra2Rad(trunc_input);
00579 
00580     CALCAMNT tmp_num = static_cast<double>(trunc_input);
00581     _last_number = KNumber(double(COS(tmp_num)));
00582 }
00583 
00584 void CalcEngine::CosHyp(KNumber input)
00585 {
00586     if (input.type() == KNumber::SpecialType) {
00587         if (input == KNumber("nan")) _last_number = KNumber("nan");
00588         if (input == KNumber("inf")) _last_number = KNumber("inf");
00589         if (input == KNumber("-inf"))  _last_number = KNumber("inf");
00590         return;
00591     }
00592 
00593     CALCAMNT tmp_num = static_cast<double>(input);
00594     _last_number = KNumber(double(COSH(tmp_num)));
00595 }
00596 
00597 void CalcEngine::Cube(KNumber input)
00598 {
00599     _last_number = input*input*input;
00600 }
00601 
00602 void CalcEngine::CubeRoot(KNumber input)
00603 {
00604     _last_number = input.cbrt();
00605 }
00606 
00607 void CalcEngine::Exp(KNumber input)
00608 {
00609     if (input.type() == KNumber::SpecialType) {
00610         if (input == KNumber("nan")) _last_number = KNumber("nan");
00611         if (input == KNumber("inf")) _last_number = KNumber("inf");
00612         if (input == KNumber("-inf"))  _last_number = KNumber::Zero;
00613         return;
00614     }
00615     CALCAMNT tmp_num = static_cast<double>(input);
00616     _last_number = KNumber(double(EXP(tmp_num)));
00617 }
00618 
00619 void CalcEngine::Exp10(KNumber input)
00620 {
00621     if (input.type() == KNumber::SpecialType) {
00622         if (input == KNumber("nan")) _last_number = KNumber("nan");
00623         if (input == KNumber("inf")) _last_number = KNumber("inf");
00624         if (input == KNumber("-inf"))  _last_number = KNumber::Zero;
00625         return;
00626     }
00627     _last_number = KNumber(10).power(input);
00628 }
00629 
00630 
00631 static KNumber _factorial(KNumber input)
00632 {
00633     KNumber tmp_amount = input;
00634 
00635     // don't do recursive factorial,
00636     // because large numbers lead to
00637     // stack overflows
00638     while (tmp_amount > KNumber::One)
00639     {
00640         tmp_amount -= KNumber::One;
00641 
00642         input = tmp_amount * input;
00643 
00644     }
00645 
00646     if (tmp_amount < KNumber::One)
00647         return KNumber::One;
00648     return input;
00649 }
00650 
00651 
00652 void CalcEngine::Factorial(KNumber input)
00653 {
00654     if (input == KNumber("inf")) return;
00655     if (input < KNumber::Zero || input.type() == KNumber::SpecialType)
00656     {
00657         _error = true;
00658         _last_number = KNumber("nan");
00659         return;
00660     }
00661     KNumber tmp_amount = input.integerPart();
00662 
00663     _last_number = _factorial(tmp_amount);
00664 }
00665 
00666 void CalcEngine::InvertSign(KNumber input)
00667 {
00668     _last_number = -input;
00669 }
00670 
00671 void CalcEngine::Ln(KNumber input)
00672 {
00673     if (input.type() == KNumber::SpecialType) {
00674         if (input == KNumber("nan")) _last_number = KNumber("nan");
00675         if (input == KNumber("inf")) _last_number = KNumber("inf");
00676         if (input == KNumber("-inf"))  _last_number = KNumber("nan");
00677         return;
00678     }
00679     if (input < KNumber::Zero)
00680         _last_number = KNumber("nan");
00681     else if (input == KNumber::Zero)
00682         _last_number = KNumber("-inf");
00683     else if (input == KNumber::One)
00684         _last_number = 0;
00685     else {
00686         CALCAMNT tmp_num = static_cast<double>(input);
00687         _last_number = KNumber(double(LN(tmp_num)));
00688     }
00689 }
00690 
00691 void CalcEngine::Log10(KNumber input)
00692 {
00693     if (input.type() == KNumber::SpecialType) {
00694         if (input == KNumber("nan")) _last_number = KNumber("nan");
00695         if (input == KNumber("inf")) _last_number = KNumber("inf");
00696         if (input == KNumber("-inf"))  _last_number = KNumber("nan");
00697         return;
00698     }
00699     if (input < KNumber::Zero)
00700         _last_number = KNumber("nan");
00701     else if (input == KNumber::Zero)
00702         _last_number = KNumber("-inf");
00703     else if (input == KNumber::One)
00704         _last_number = 0;
00705     else {
00706         CALCAMNT tmp_num = static_cast<double>(input);
00707         _last_number = KNumber(double(LOG_TEN(tmp_num)));
00708     }
00709 }
00710 
00711 void CalcEngine::ParenClose(KNumber input)
00712 {
00713     // evaluate stack until corresponding opening bracket
00714     while (!_stack.isEmpty())
00715     {
00716         _node tmp_node = _stack.pop();
00717         if (tmp_node.operation == FUNC_BRACKET)
00718             break;
00719         input = evalOperation(tmp_node.number, tmp_node.operation,
00720                       input);
00721     }
00722     _last_number = input;
00723     return;
00724 }
00725 
00726 void CalcEngine::ParenOpen(KNumber input)
00727 {
00728     enterOperation(input, FUNC_BRACKET);
00729 }
00730 
00731 void CalcEngine::Reciprocal(KNumber input)
00732 {
00733     _last_number = KNumber::One/input;
00734 }
00735 
00736 
00737 void CalcEngine::SinDeg(KNumber input)
00738 {
00739     if (input.type() == KNumber::SpecialType) {
00740         _last_number = KNumber("nan");
00741         return;
00742     }
00743 
00744     KNumber trunc_input = moveIntoDegInterval(input);
00745     if (trunc_input.type() == KNumber::IntegerType) {
00746         KNumber mult = trunc_input/KNumber(90);
00747         if (mult.type() == KNumber::IntegerType) {
00748           if (mult == KNumber::Zero)
00749             _last_number = 0;
00750           else if (mult == KNumber(1))
00751             _last_number = 1;
00752           else if (mult == KNumber(2))
00753             _last_number = 0;
00754           else if (mult == KNumber(3))
00755             _last_number = -1;
00756           else qDebug("Something wrong in CalcEngine::SinDeg\n");
00757           return;
00758         }
00759     }
00760     trunc_input = Deg2Rad(trunc_input);
00761 
00762     CALCAMNT tmp_num = static_cast<double>(trunc_input);
00763     _last_number = KNumber(double(SIN(tmp_num)));
00764 }
00765 
00766 void CalcEngine::SinRad(KNumber input)
00767 {
00768     if (input.type() == KNumber::SpecialType) {
00769         _last_number = KNumber("nan");
00770         return;
00771     }
00772 
00773     CALCAMNT tmp_num = static_cast<double>(input);
00774     _last_number = KNumber(double(SIN(tmp_num)));
00775 }
00776 
00777 void CalcEngine::SinGrad(KNumber input)
00778 {
00779     if (input.type() == KNumber::SpecialType) {
00780         _last_number = KNumber("nan");
00781         return;
00782     }
00783 
00784     KNumber trunc_input = moveIntoGradInterval(input);
00785     if (trunc_input.type() == KNumber::IntegerType) {
00786         KNumber mult = trunc_input/KNumber(100);
00787         if (mult.type() == KNumber::IntegerType) {
00788           if (mult == KNumber::Zero)
00789             _last_number = 0;
00790           else if (mult == KNumber(1))
00791             _last_number = 1;
00792           else if (mult == KNumber(2))
00793             _last_number = 0;
00794           else if (mult == KNumber(3))
00795             _last_number = -1;
00796           else qDebug("Something wrong in CalcEngine::SinGrad\n");
00797           return;
00798         }
00799     }
00800 
00801     trunc_input = Gra2Rad(trunc_input);
00802 
00803     CALCAMNT tmp_num = static_cast<double>(trunc_input);
00804     _last_number = KNumber(double(SIN(tmp_num)));
00805 }
00806 
00807 void CalcEngine::SinHyp(KNumber input)
00808 {
00809     if (input.type() == KNumber::SpecialType) {
00810         if (input == KNumber("nan")) _last_number = KNumber("nan");
00811         if (input == KNumber("inf")) _last_number = KNumber("inf");
00812         if (input == KNumber("-inf"))  _last_number = KNumber("-inf");
00813         return;
00814     }
00815 
00816     CALCAMNT tmp_num = static_cast<double>(input);
00817     _last_number = KNumber(double(SINH(tmp_num)));
00818 }
00819 
00820 void CalcEngine::Square(KNumber input)
00821 {
00822     _last_number = input*input;
00823 }
00824 
00825 void CalcEngine::SquareRoot(KNumber input)
00826 {
00827     _last_number = input.sqrt();
00828 }
00829 
00830 void CalcEngine::StatClearAll(KNumber input)
00831 {
00832     UNUSED(input);
00833     stats.clearAll();
00834 }
00835 
00836 void CalcEngine::StatCount(KNumber input)
00837 {
00838     UNUSED(input);
00839     _last_number = KNumber(stats.count());
00840 }
00841 
00842 void CalcEngine::StatDataNew(KNumber input)
00843 {
00844     stats.enterData(input);
00845     _last_number = KNumber(stats.count());
00846 }
00847 
00848 void CalcEngine::StatDataDel(KNumber input)
00849 {
00850     UNUSED(input);
00851     stats.clearLast();
00852     _last_number = KNumber::Zero;
00853 }
00854 
00855 void CalcEngine::StatMean(KNumber input)
00856 {
00857     UNUSED(input);
00858     _last_number = stats.mean();
00859 
00860     _error = stats.error();
00861 }
00862 
00863 void CalcEngine::StatMedian(KNumber input)
00864 {
00865     UNUSED(input);
00866     _last_number = stats.median();
00867 
00868     _error = stats.error();
00869 }
00870 
00871 void CalcEngine::StatStdDeviation(KNumber input)
00872 {
00873     UNUSED(input);
00874     _last_number = stats.std();
00875 
00876     _error = stats.error();
00877 }
00878 
00879 void CalcEngine::StatStdSample(KNumber input)
00880 {
00881     UNUSED(input);
00882     _last_number = stats.sample_std();
00883 
00884     _error = stats.error();
00885 }
00886 
00887 void CalcEngine::StatSum(KNumber input)
00888 {
00889     UNUSED(input);
00890     _last_number = stats.sum();
00891 }
00892 
00893 void CalcEngine::StatSumSquares(KNumber input)
00894 {
00895     UNUSED(input);
00896     _last_number = stats.sum_of_squares();
00897 
00898     _error = stats.error();
00899 }
00900 
00901 void CalcEngine::TangensDeg(KNumber input)
00902 {
00903     if (input.type() == KNumber::SpecialType) {
00904         _last_number = KNumber("nan");
00905         return;
00906     }
00907 
00908     SinDeg(input);
00909     KNumber arg1 = _last_number;
00910     CosDeg(input);
00911     KNumber arg2 = _last_number;
00912     _last_number = arg1 / arg2;
00913 }
00914 
00915 void CalcEngine::TangensRad(KNumber input)
00916 {
00917     if (input.type() == KNumber::SpecialType) {
00918         _last_number = KNumber("nan");
00919         return;
00920     }
00921 
00922     SinRad(input);
00923     KNumber arg1 = _last_number;
00924     CosRad(input);
00925     KNumber arg2 = _last_number;
00926     _last_number = arg1 / arg2;
00927 }
00928 
00929 void CalcEngine::TangensGrad(KNumber input)
00930 {
00931     if (input.type() ==