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