File indexing completed on 2024-05-12 04:45:52

0001 /*
0002 Copyright (C) 2001 - 2013 Evan Teran
0003                           evan.teran@gmail.com
0004 
0005 This program is free software: you can redistribute it and/or modify
0006 it under the terms of the GNU General Public License as published by
0007 the Free Software Foundation, either version 2 of the License, or
0008 (at your option) any later version.
0009 
0010 This program is distributed in the hope that it will be useful,
0011 but WITHOUT ANY WARRANTY; without even the implied warranty of
0012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0013 GNU General Public License for more details.
0014 
0015 You should have received a copy of the GNU General Public License
0016 along with this program.  If not, see <http://www.gnu.org/licenses/>.
0017 */
0018 
0019 #include <config-kcalc.h>
0020 #include "knumber_integer.h"
0021 #include "knumber_float.h"
0022 #include "knumber_fraction.h"
0023 #include "knumber_error.h"
0024 #include <cmath> // for M_PI
0025 
0026 namespace detail {
0027 
0028 
0029 //------------------------------------------------------------------------------
0030 // Name:
0031 //------------------------------------------------------------------------------
0032 knumber_error::knumber_error(Error e) : error_(e) {
0033 }
0034 
0035 //------------------------------------------------------------------------------
0036 // Name:
0037 //------------------------------------------------------------------------------
0038 knumber_error::knumber_error(const QString &s) {
0039 
0040     if (s == QLatin1String("nan"))       error_ = ERROR_UNDEFINED;
0041     else if (s == QLatin1String("inf"))  error_ = ERROR_POS_INFINITY;
0042     else if (s == QLatin1String("-inf")) error_ = ERROR_NEG_INFINITY;
0043     else                                 error_ = ERROR_UNDEFINED;
0044 }
0045 
0046 //------------------------------------------------------------------------------
0047 // Name:
0048 //------------------------------------------------------------------------------
0049 knumber_error::knumber_error() : error_(ERROR_UNDEFINED) {
0050 
0051 }
0052 
0053 //------------------------------------------------------------------------------
0054 // Name:
0055 //------------------------------------------------------------------------------
0056 knumber_error::~knumber_error() {
0057 
0058 }
0059 
0060 //------------------------------------------------------------------------------
0061 // Name:
0062 //------------------------------------------------------------------------------
0063 knumber_error::knumber_error(const knumber_integer *) : error_(ERROR_UNDEFINED) {
0064 }
0065 
0066 //------------------------------------------------------------------------------
0067 // Name:
0068 //------------------------------------------------------------------------------
0069 knumber_error::knumber_error(const knumber_fraction *) : error_(ERROR_UNDEFINED) {
0070 }
0071 
0072 //------------------------------------------------------------------------------
0073 // Name:
0074 //------------------------------------------------------------------------------
0075 knumber_error::knumber_error(const knumber_float *) : error_(ERROR_UNDEFINED) {
0076 }
0077 
0078 //------------------------------------------------------------------------------
0079 // Name:
0080 //------------------------------------------------------------------------------
0081 knumber_error::knumber_error(const knumber_error *value) : error_(value->error_) {
0082 }
0083 
0084 //------------------------------------------------------------------------------
0085 // Name:
0086 //------------------------------------------------------------------------------
0087 QString knumber_error::toString(int precision) const {
0088 
0089     Q_UNUSED(precision);
0090 
0091     switch(error_) {
0092     case ERROR_POS_INFINITY:
0093         return QStringLiteral("inf");
0094     case ERROR_NEG_INFINITY:
0095         return QStringLiteral("-inf");
0096     case ERROR_UNDEFINED:
0097     default:
0098         return QStringLiteral("nan");
0099     }
0100 }
0101 QString knumber_error::toBinaryString(int precision) const {
0102 
0103     Q_UNUSED(precision);
0104 
0105     switch(error_) {
0106     case ERROR_POS_INFINITY:
0107         return QStringLiteral("inf");
0108     case ERROR_NEG_INFINITY:
0109         return QStringLiteral("-inf");
0110     case ERROR_UNDEFINED:
0111     default:
0112         return QStringLiteral("nan");
0113     }
0114 }
0115 QString knumber_error::toHexString(int precision) const {
0116     Q_UNUSED(precision);
0117 
0118     switch(error_) {
0119     case ERROR_POS_INFINITY:
0120         return QStringLiteral("inf");
0121     case ERROR_NEG_INFINITY:
0122         return QStringLiteral("-inf");
0123     case ERROR_UNDEFINED:
0124     default:
0125         return QStringLiteral("nan");
0126     }
0127 }
0128 //------------------------------------------------------------------------------
0129 // Name:
0130 //------------------------------------------------------------------------------
0131 knumber_base *knumber_error::add(knumber_base *rhs) {
0132 
0133     if(knumber_integer *const p = dynamic_cast<knumber_integer *>(rhs)) {
0134         Q_UNUSED(p);
0135         return this;
0136     } else if(knumber_float *const p = dynamic_cast<knumber_float *>(rhs)) {
0137         Q_UNUSED(p);
0138         return this;
0139     } else if(knumber_fraction *const p = dynamic_cast<knumber_fraction *>(rhs)) {
0140         Q_UNUSED(p);
0141         return this;
0142     } else if(knumber_error *const p = dynamic_cast<knumber_error *>(rhs)) {
0143         if(error_ == ERROR_POS_INFINITY && p->error_ == ERROR_NEG_INFINITY) {
0144             error_ = ERROR_UNDEFINED;
0145         } else if(error_ == ERROR_NEG_INFINITY && p->error_ == ERROR_POS_INFINITY) {
0146             error_ = ERROR_UNDEFINED;
0147         } else if(p->error_ == ERROR_UNDEFINED) {
0148             error_ = ERROR_UNDEFINED;
0149         }
0150         return this;
0151     }
0152 
0153     Q_ASSERT(0);
0154     return nullptr;
0155 }
0156 
0157 //------------------------------------------------------------------------------
0158 // Name:
0159 //------------------------------------------------------------------------------
0160 knumber_base *knumber_error::sub(knumber_base *rhs) {
0161 
0162     if(knumber_integer *const p = dynamic_cast<knumber_integer *>(rhs)) {
0163         Q_UNUSED(p);
0164         return this;
0165     } else if(knumber_float *const p = dynamic_cast<knumber_float *>(rhs)) {
0166         Q_UNUSED(p);
0167         return this;
0168     } else if(knumber_fraction *const p = dynamic_cast<knumber_fraction *>(rhs)) {
0169         Q_UNUSED(p);
0170         return this;
0171     } else if(knumber_error *const p = dynamic_cast<knumber_error *>(rhs)) {
0172         if(error_ == ERROR_POS_INFINITY && p->error_ == ERROR_POS_INFINITY) {
0173             error_ = ERROR_UNDEFINED;
0174         } else if(error_ == ERROR_NEG_INFINITY && p->error_ == ERROR_NEG_INFINITY) {
0175             error_ = ERROR_UNDEFINED;
0176         } else if(p->error_ == ERROR_UNDEFINED) {
0177             error_ = ERROR_UNDEFINED;
0178         }
0179         return this;
0180     }
0181 
0182     Q_ASSERT(0);
0183     return nullptr;
0184 }
0185 
0186 //------------------------------------------------------------------------------
0187 // Name:
0188 //------------------------------------------------------------------------------
0189 knumber_base *knumber_error::mul(knumber_base *rhs) {
0190 
0191     if(knumber_integer *const p = dynamic_cast<knumber_integer *>(rhs)) {
0192         if(p->is_zero()) {
0193             error_ = ERROR_UNDEFINED;
0194         }
0195         return this;
0196     } else if(knumber_float *const p = dynamic_cast<knumber_float *>(rhs)) {
0197         if(p->is_zero()) {
0198             error_ = ERROR_UNDEFINED;
0199         }
0200         return this;
0201     } else if(knumber_fraction *const p = dynamic_cast<knumber_fraction *>(rhs)) {
0202         if(p->is_zero()) {
0203             error_ = ERROR_UNDEFINED;
0204         }
0205         return this;
0206     } else if(knumber_error *const p = dynamic_cast<knumber_error *>(rhs)) {
0207         if(error_ == ERROR_POS_INFINITY && p->error_ == ERROR_NEG_INFINITY) {
0208             error_ = ERROR_NEG_INFINITY;
0209         } else if(error_ == ERROR_NEG_INFINITY && p->error_ == ERROR_POS_INFINITY) {
0210             error_ = ERROR_NEG_INFINITY;
0211         } else if(error_ == ERROR_NEG_INFINITY && p->error_ == ERROR_NEG_INFINITY) {
0212             error_ = ERROR_POS_INFINITY;
0213         } else if(p->error_ == ERROR_UNDEFINED) {
0214             error_ = ERROR_UNDEFINED;
0215         }
0216         return this;
0217     }
0218 
0219     Q_ASSERT(0);
0220     return nullptr;
0221 }
0222 
0223 //------------------------------------------------------------------------------
0224 // Name:
0225 //------------------------------------------------------------------------------
0226 knumber_base *knumber_error::div(knumber_base *rhs) {
0227 
0228     if(knumber_integer *const p = dynamic_cast<knumber_integer *>(rhs)) {
0229         Q_UNUSED(p);
0230         return this;
0231     } else if(knumber_float *const p = dynamic_cast<knumber_float *>(rhs)) {
0232         Q_UNUSED(p);
0233         return this;
0234     } else if(knumber_fraction *const p = dynamic_cast<knumber_fraction *>(rhs)) {
0235         Q_UNUSED(p);
0236         return this;
0237     } else if(knumber_error *const p = dynamic_cast<knumber_error *>(rhs)) {
0238         Q_UNUSED(p);
0239         error_ = ERROR_UNDEFINED;
0240         return this;
0241     }
0242 
0243     Q_ASSERT(0);
0244     return nullptr;
0245 }
0246 
0247 //------------------------------------------------------------------------------
0248 // Name:
0249 //------------------------------------------------------------------------------
0250 knumber_base *knumber_error::mod(knumber_base *rhs) {
0251 
0252     if(knumber_integer *const p = dynamic_cast<knumber_integer *>(rhs)) {
0253         Q_UNUSED(p);
0254         return this;
0255     } else if(knumber_float *const p = dynamic_cast<knumber_float *>(rhs)) {
0256         Q_UNUSED(p);
0257         return this;
0258     } else if(knumber_fraction *const p = dynamic_cast<knumber_fraction *>(rhs)) {
0259         Q_UNUSED(p);
0260         return this;
0261     } else if(knumber_error *const p = dynamic_cast<knumber_error *>(rhs)) {
0262         Q_UNUSED(p);
0263         error_ = ERROR_UNDEFINED;
0264         return this;
0265     }
0266 
0267     Q_ASSERT(0);
0268     return nullptr;
0269 }
0270 
0271 //------------------------------------------------------------------------------
0272 // Name:
0273 //------------------------------------------------------------------------------
0274 knumber_base *knumber_error::pow(knumber_base *rhs) {
0275 
0276     if(knumber_integer *const p = dynamic_cast<knumber_integer *>(rhs)) {
0277         Q_UNUSED(p);
0278         return this;
0279     } else if(knumber_float *const p = dynamic_cast<knumber_float *>(rhs)) {
0280         Q_UNUSED(p);
0281         return this;
0282     } else if(knumber_fraction *const p = dynamic_cast<knumber_fraction *>(rhs)) {
0283         Q_UNUSED(p);
0284         return this;
0285     } else if(knumber_error *const p = dynamic_cast<knumber_error *>(rhs)) {
0286 
0287         switch(error_) {
0288         case ERROR_POS_INFINITY:
0289             if(p->sign() > 0) {
0290                 return this;
0291             } else if(p->sign() < 0) {
0292                 knumber_integer *n = new knumber_integer(0);
0293                 delete this;
0294                 return n;
0295             } else {
0296                 error_ = ERROR_UNDEFINED;
0297                 return this;
0298             }
0299             break;
0300         case ERROR_NEG_INFINITY:
0301             if(p->sign() > 0) {
0302                 error_ = ERROR_POS_INFINITY;
0303                 return this;
0304             } else if(p->sign() < 0) {
0305                 knumber_integer *n = new knumber_integer(0);
0306                 delete this;
0307                 return n;
0308             } else {
0309                 error_ = ERROR_UNDEFINED;
0310                 return this;
0311             }
0312             break;
0313         case ERROR_UNDEFINED:
0314             return this;
0315         }
0316     }
0317 
0318     Q_ASSERT(0);
0319     return nullptr;
0320 }
0321 
0322 //------------------------------------------------------------------------------
0323 // Name:
0324 //------------------------------------------------------------------------------
0325 knumber_base *knumber_error::neg() {
0326 
0327     switch(error_) {
0328     case ERROR_POS_INFINITY:
0329         error_ = ERROR_NEG_INFINITY;
0330         break;
0331     case ERROR_NEG_INFINITY:
0332         error_ = ERROR_POS_INFINITY;
0333         break;
0334     case ERROR_UNDEFINED:
0335     default:
0336         break;
0337     }
0338 
0339     return this;
0340 }
0341 
0342 //------------------------------------------------------------------------------
0343 // Name:
0344 //------------------------------------------------------------------------------
0345 knumber_base *knumber_error::cmp() {
0346 
0347     error_ = ERROR_UNDEFINED;
0348     return this;
0349 }
0350 
0351 //------------------------------------------------------------------------------
0352 // Name:
0353 //------------------------------------------------------------------------------
0354 knumber_base *knumber_error::abs() {
0355 
0356     switch(error_) {
0357     case ERROR_NEG_INFINITY:
0358         error_ = ERROR_POS_INFINITY;
0359         break;
0360     case ERROR_POS_INFINITY:
0361     case ERROR_UNDEFINED:
0362     default:
0363         break;
0364     }
0365 
0366     return this;
0367 }
0368 
0369 //------------------------------------------------------------------------------
0370 // Name:
0371 //------------------------------------------------------------------------------
0372 knumber_base *knumber_error::sqrt() {
0373 
0374     switch(error_) {
0375     case ERROR_NEG_INFINITY:
0376         error_ = ERROR_UNDEFINED;
0377         break;
0378     case ERROR_POS_INFINITY:
0379     case ERROR_UNDEFINED:
0380     default:
0381         break;
0382     }
0383 
0384     return this;
0385 }
0386 
0387 //------------------------------------------------------------------------------
0388 // Name:
0389 //------------------------------------------------------------------------------
0390 knumber_base *knumber_error::cbrt() {
0391 
0392     return this;
0393 }
0394 
0395 //------------------------------------------------------------------------------
0396 // Name:
0397 //------------------------------------------------------------------------------
0398 knumber_base *knumber_error::factorial() {
0399     error_ = ERROR_UNDEFINED;
0400     return this;
0401 }
0402 
0403 //------------------------------------------------------------------------------
0404 // Name:
0405 //------------------------------------------------------------------------------
0406 knumber_base *knumber_error::sin() {
0407 
0408     error_ = ERROR_UNDEFINED;
0409     return this;
0410 }
0411 
0412 //------------------------------------------------------------------------------
0413 // Name:
0414 //------------------------------------------------------------------------------
0415 knumber_base *knumber_error::cos() {
0416 
0417     error_ = ERROR_UNDEFINED;
0418     return this;
0419 }
0420 
0421 //------------------------------------------------------------------------------
0422 // Name:
0423 //------------------------------------------------------------------------------
0424 knumber_base* knumber_error::tgamma() {
0425 
0426     error_ = ERROR_UNDEFINED;
0427     return this;
0428 }
0429 
0430 //------------------------------------------------------------------------------
0431 // Name:
0432 //------------------------------------------------------------------------------
0433 knumber_base *knumber_error::tan() {
0434 
0435     error_ = ERROR_UNDEFINED;
0436     return this;
0437 }
0438 
0439 //------------------------------------------------------------------------------
0440 // Name:
0441 //------------------------------------------------------------------------------
0442 knumber_base *knumber_error::asin() {
0443 
0444     error_ = ERROR_UNDEFINED;
0445     return this;
0446 }
0447 
0448 //------------------------------------------------------------------------------
0449 // Name:
0450 //------------------------------------------------------------------------------
0451 knumber_base *knumber_error::acos() {
0452 
0453     error_ = ERROR_UNDEFINED;
0454     return this;
0455 }
0456 
0457 //------------------------------------------------------------------------------
0458 // Name:
0459 //------------------------------------------------------------------------------
0460 knumber_base *knumber_error::atan() {
0461 
0462     switch(error_) {
0463     case ERROR_POS_INFINITY:
0464         delete this;
0465         return new knumber_float(M_PI / 2.0);
0466     case ERROR_NEG_INFINITY:
0467         delete this;
0468         return new knumber_float(-M_PI / 2.0);
0469     case ERROR_UNDEFINED:
0470     default:
0471         return this;
0472     }
0473 }
0474 
0475 //------------------------------------------------------------------------------
0476 // Name:
0477 //------------------------------------------------------------------------------
0478 knumber_base *knumber_error::sinh() {
0479 
0480     return this;
0481 }
0482 
0483 //------------------------------------------------------------------------------
0484 // Name:
0485 //------------------------------------------------------------------------------
0486 knumber_base *knumber_error::cosh() {
0487 
0488     error_ = ERROR_UNDEFINED;
0489     return this;
0490 }
0491 
0492 //------------------------------------------------------------------------------
0493 // Name:
0494 //------------------------------------------------------------------------------
0495 knumber_base *knumber_error::tanh() {
0496 
0497     if(sign() > 0) {
0498         delete this;
0499         return new knumber_integer(1);
0500     } else if(sign() < 0) {
0501         delete this;
0502         return new knumber_integer(-1);
0503     } else {
0504         return this;
0505     }
0506 }
0507 
0508 //------------------------------------------------------------------------------
0509 // Name:
0510 //------------------------------------------------------------------------------
0511 knumber_base *knumber_error::asinh() {
0512 
0513     return this;
0514 }
0515 
0516 //------------------------------------------------------------------------------
0517 // Name:
0518 //------------------------------------------------------------------------------
0519 knumber_base *knumber_error::acosh() {
0520 
0521     if(sign() < 0) {
0522         error_ = ERROR_UNDEFINED;
0523     }
0524 
0525     return this;
0526 }
0527 
0528 //------------------------------------------------------------------------------
0529 // Name:
0530 //------------------------------------------------------------------------------
0531 knumber_base *knumber_error::atanh() {
0532 
0533     error_ = ERROR_UNDEFINED;
0534     return this;
0535 }
0536 
0537 //------------------------------------------------------------------------------
0538 // Name:
0539 //------------------------------------------------------------------------------
0540 int knumber_error::compare(knumber_base *rhs) {
0541 
0542     if(knumber_integer *const p = dynamic_cast<knumber_integer *>(rhs)) {
0543         if(sign() > 0) {
0544             return 1;
0545         } else {
0546             return -1;
0547         }
0548     } else if(knumber_float *const p = dynamic_cast<knumber_float *>(rhs)) {
0549         if(sign() > 0) {
0550             return 1;
0551         } else {
0552             return -1;
0553         }
0554     } else if(knumber_fraction *const p = dynamic_cast<knumber_fraction *>(rhs)) {
0555         if(sign() > 0) {
0556             return 1;
0557         } else {
0558             return -1;
0559         }
0560     } else if(knumber_error *const p = dynamic_cast<knumber_error *>(rhs)) {
0561         return sign() == p->sign();
0562     }
0563 
0564     Q_ASSERT(0);
0565     return 0;
0566 }
0567 
0568 //------------------------------------------------------------------------------
0569 // Name:
0570 //------------------------------------------------------------------------------
0571 knumber_base *knumber_error::clone() {
0572     return new knumber_error(this);
0573 }
0574 
0575 //------------------------------------------------------------------------------
0576 // Name:
0577 //------------------------------------------------------------------------------
0578 knumber_base *knumber_error::bitwise_and(knumber_base *rhs) {
0579     Q_UNUSED(rhs);
0580     error_ = ERROR_UNDEFINED;
0581     return this;
0582 }
0583 
0584 //------------------------------------------------------------------------------
0585 // Name:
0586 //------------------------------------------------------------------------------
0587 knumber_base *knumber_error::bitwise_xor(knumber_base *rhs) {
0588     Q_UNUSED(rhs);
0589     error_ = ERROR_UNDEFINED;
0590     return this;
0591 }
0592 
0593 //------------------------------------------------------------------------------
0594 // Name:
0595 //------------------------------------------------------------------------------
0596 knumber_base *knumber_error::bitwise_or(knumber_base *rhs) {
0597     Q_UNUSED(rhs);
0598     error_ = ERROR_UNDEFINED;
0599     return this;
0600 }
0601 
0602 //------------------------------------------------------------------------------
0603 // Name:
0604 //------------------------------------------------------------------------------
0605 knumber_base *knumber_error::bitwise_shift(knumber_base *rhs) {
0606     Q_UNUSED(rhs);
0607     error_ = ERROR_UNDEFINED;
0608     return this;
0609 }
0610 
0611 //------------------------------------------------------------------------------
0612 // Name:
0613 //------------------------------------------------------------------------------
0614 bool knumber_error::is_integer() const {
0615 
0616     return false;
0617 }
0618 
0619 //------------------------------------------------------------------------------
0620 // Name:
0621 //------------------------------------------------------------------------------
0622 bool knumber_error::is_zero() const {
0623 
0624     return false;
0625 }
0626 
0627 //------------------------------------------------------------------------------
0628 // Name:
0629 //------------------------------------------------------------------------------
0630 int knumber_error::sign() const {
0631 
0632     switch(error_) {
0633     case ERROR_POS_INFINITY:
0634         return +1;
0635     case ERROR_NEG_INFINITY:
0636         return -1;
0637     case ERROR_UNDEFINED:
0638     default:
0639         return 0;
0640     }
0641 }
0642 
0643 //------------------------------------------------------------------------------
0644 // Name:
0645 //------------------------------------------------------------------------------
0646 knumber_base *knumber_error::reciprocal() {
0647 
0648     error_ = ERROR_UNDEFINED;
0649     return this;
0650 }
0651 
0652 //------------------------------------------------------------------------------
0653 // Name:
0654 //------------------------------------------------------------------------------
0655 knumber_base *knumber_error::log2() {
0656     error_ = ERROR_UNDEFINED;
0657     return this;
0658 }
0659 
0660 //------------------------------------------------------------------------------
0661 // Name:
0662 //------------------------------------------------------------------------------
0663 knumber_base *knumber_error::log10() {
0664     error_ = ERROR_UNDEFINED;
0665     return this;
0666 }
0667 
0668 //------------------------------------------------------------------------------
0669 // Name:
0670 //------------------------------------------------------------------------------
0671 knumber_base *knumber_error::ln() {
0672     error_ = ERROR_UNDEFINED;
0673     return this;
0674 }
0675 
0676 //------------------------------------------------------------------------------
0677 // Name:
0678 //------------------------------------------------------------------------------
0679 knumber_base *knumber_error::ceil() {
0680     error_ = ERROR_UNDEFINED;
0681     return this;
0682 }
0683 
0684 //------------------------------------------------------------------------------
0685 // Name:
0686 //------------------------------------------------------------------------------
0687 knumber_base *knumber_error::floor() {
0688     error_ = ERROR_UNDEFINED;
0689     return this;
0690 }
0691 
0692 //------------------------------------------------------------------------------
0693 // Name:
0694 //------------------------------------------------------------------------------
0695 knumber_base *knumber_error::exp2() {
0696     error_ = ERROR_UNDEFINED;
0697     return this;
0698 }
0699 
0700 //------------------------------------------------------------------------------
0701 // Name:
0702 //------------------------------------------------------------------------------
0703 knumber_base *knumber_error::exp10() {
0704     error_ = ERROR_UNDEFINED;
0705     return this;
0706 }
0707 
0708 //------------------------------------------------------------------------------
0709 // Name:
0710 //------------------------------------------------------------------------------
0711 knumber_base *knumber_error::exp() {
0712     error_ = ERROR_UNDEFINED;
0713     return this;
0714 }
0715 
0716 //------------------------------------------------------------------------------
0717 // Name:
0718 //------------------------------------------------------------------------------
0719 quint64 knumber_error::toUint64() const {
0720     return 0;
0721 }
0722 
0723 //------------------------------------------------------------------------------
0724 // Name:
0725 //------------------------------------------------------------------------------
0726 qint64 knumber_error::toInt64() const {
0727     return 0;
0728 }
0729 
0730 //------------------------------------------------------------------------------
0731 // Name:
0732 //------------------------------------------------------------------------------
0733 knumber_base *knumber_error::bin(knumber_base *rhs) {
0734     Q_UNUSED(rhs);
0735     error_ = ERROR_UNDEFINED;
0736     return this;
0737 }
0738 
0739 }