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 }