File indexing completed on 2024-05-12 17:21:04

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