File indexing completed on 2024-04-28 09:45:22
0001 /* 0002 SPDX-FileCopyrightText: 2001-2013 Evan Teran <evan.teran@gmail.com> 0003 0004 SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 // clang-format off 0007 #include "config-kcalc.h" 0008 // clang-format on 0009 #include "knumber.h" 0010 #include "knumber_base.h" 0011 #include "knumber_error.h" 0012 #include "knumber_float.h" 0013 #include "knumber_fraction.h" 0014 #include "knumber_integer.h" 0015 #include <QRegExp> 0016 #include <QStringList> 0017 #include <cmath> 0018 0019 QString KNumber::GroupSeparator = QStringLiteral(","); 0020 QString KNumber::DecimalSeparator = QStringLiteral("."); 0021 0022 const KNumber KNumber::Zero(QStringLiteral("0")); 0023 const KNumber KNumber::One(QStringLiteral("1")); 0024 const KNumber KNumber::NegOne(QStringLiteral("-1")); 0025 const KNumber KNumber::PosInfinity(QStringLiteral("inf")); 0026 const KNumber KNumber::NegInfinity(QStringLiteral("-inf")); 0027 const KNumber KNumber::NaN(QStringLiteral("nan")); 0028 0029 namespace 0030 { 0031 namespace impl 0032 { 0033 //------------------------------------------------------------------------------ 0034 // Name: increment 0035 //------------------------------------------------------------------------------ 0036 void increment(QString &str, int position) 0037 { 0038 for (int i = position; i >= 0; i--) { 0039 const char last_char = str[i].toLatin1(); 0040 switch (last_char) { 0041 case '0': 0042 str[i] = QLatin1Char('1'); 0043 break; 0044 case '1': 0045 str[i] = QLatin1Char('2'); 0046 break; 0047 case '2': 0048 str[i] = QLatin1Char('3'); 0049 break; 0050 case '3': 0051 str[i] = QLatin1Char('4'); 0052 break; 0053 case '4': 0054 str[i] = QLatin1Char('5'); 0055 break; 0056 case '5': 0057 str[i] = QLatin1Char('6'); 0058 break; 0059 case '6': 0060 str[i] = QLatin1Char('7'); 0061 break; 0062 case '7': 0063 str[i] = QLatin1Char('8'); 0064 break; 0065 case '8': 0066 str[i] = QLatin1Char('9'); 0067 break; 0068 case '9': 0069 str[i] = QLatin1Char('0'); 0070 if (i == 0) { 0071 str.prepend(QLatin1Char('1')); 0072 } 0073 continue; 0074 case '.': 0075 continue; 0076 } 0077 break; 0078 } 0079 } 0080 0081 //------------------------------------------------------------------------------ 0082 // Name: round 0083 //------------------------------------------------------------------------------ 0084 void round(QString &str, int precision) 0085 { 0086 int decimalSymbolPos = str.indexOf(QLatin1Char('.')); 0087 if (decimalSymbolPos == -1) { 0088 if (precision == 0) { 0089 return; 0090 } else { 0091 str.append(QLatin1Char('.')); 0092 str.append(QString().fill(QLatin1Char('0'), precision)); 0093 return; 0094 } 0095 } else { 0096 int desiredLength = decimalSymbolPos + precision + 1; 0097 int extraZeroNeeded = desiredLength - str.length(); 0098 0099 if (extraZeroNeeded == 0) { 0100 return; 0101 } else if (extraZeroNeeded > 0) { 0102 str.append(QString().fill(QLatin1Char('0'), extraZeroNeeded)); 0103 } else { 0104 // decide whether to round up or down based on the digit after desired length 0105 if (str.at(desiredLength).toLatin1() >= '5') { 0106 increment(str, desiredLength - 1); 0107 } 0108 decimalSymbolPos = str.indexOf(QLatin1Char('.')); 0109 str.truncate(decimalSymbolPos + precision + 1); 0110 } 0111 } 0112 } 0113 } 0114 0115 //------------------------------------------------------------------------------ 0116 // Name: round 0117 //------------------------------------------------------------------------------ 0118 QString round(const QString &s, int precision) 0119 { 0120 QString tmp = s; 0121 if (precision < 0 || !QRegExp(QLatin1String(R"(^[+-]?\d+(\.\d+)*(e[+-]?\d+)?$)")).exactMatch(tmp)) { 0122 return s; 0123 } 0124 0125 // Skip the sign (for now) 0126 const bool neg = (tmp[0] == QLatin1Char('-')); 0127 if (neg || tmp[0] == QLatin1Char('+')) { 0128 tmp.remove(0, 1); 0129 } 0130 0131 // Split off exponential part (including 'e'-symbol) 0132 QString mantString = tmp.section(QLatin1Char('e'), 0, 0, QString::SectionCaseInsensitiveSeps); 0133 QString expString = tmp.section(QLatin1Char('e'), 1, 1, QString::SectionCaseInsensitiveSeps | QString::SectionIncludeLeadingSep); 0134 0135 if (expString.length() == 1) { 0136 expString.clear(); 0137 } 0138 0139 impl::round(mantString, precision); 0140 0141 if (neg) { 0142 mantString.prepend(QLatin1Char('-')); 0143 } 0144 0145 return mantString + expString; 0146 } 0147 } 0148 0149 //------------------------------------------------------------------------------ 0150 // Name: setGroupSeparator 0151 //------------------------------------------------------------------------------ 0152 void KNumber::setGroupSeparator(const QString &ch) 0153 { 0154 GroupSeparator = ch; 0155 } 0156 0157 //------------------------------------------------------------------------------ 0158 // Name: setDecimalSeparator 0159 //------------------------------------------------------------------------------ 0160 void KNumber::setDecimalSeparator(const QString &ch) 0161 { 0162 DecimalSeparator = ch; 0163 } 0164 0165 //------------------------------------------------------------------------------ 0166 // Name: groupSeparator 0167 //------------------------------------------------------------------------------ 0168 QString KNumber::groupSeparator() 0169 { 0170 return GroupSeparator; 0171 } 0172 0173 //------------------------------------------------------------------------------ 0174 // Name: decimalSeparator 0175 //------------------------------------------------------------------------------ 0176 QString KNumber::decimalSeparator() 0177 { 0178 return DecimalSeparator; 0179 } 0180 0181 //------------------------------------------------------------------------------ 0182 // Name: setDefaultFloatPrecision 0183 //------------------------------------------------------------------------------ 0184 void KNumber::setDefaultFloatPrecision(int precision) 0185 { 0186 // Need to transform decimal digits into binary digits 0187 const auto bin_prec = static_cast<unsigned long int>(::ceil(precision * M_LN10 / M_LN2) + 1); 0188 mpfr_set_default_prec(static_cast<mpfr_prec_t>(bin_prec)); 0189 } 0190 0191 //------------------------------------------------------------------------------ 0192 // Name: setSplitoffIntegerForFractionOutput 0193 //------------------------------------------------------------------------------ 0194 void KNumber::setSplitoffIntegerForFractionOutput(bool x) 0195 { 0196 detail::knumber_fraction::set_split_off_integer_for_fraction_output(x); 0197 } 0198 0199 //------------------------------------------------------------------------------ 0200 // Name: setDefaultFractionalInput 0201 //------------------------------------------------------------------------------ 0202 void KNumber::setDefaultFractionalInput(bool x) 0203 { 0204 detail::knumber_fraction::set_default_fractional_input(x); 0205 } 0206 0207 //------------------------------------------------------------------------------ 0208 // Name: setDefaultFloatOutput 0209 //------------------------------------------------------------------------------ 0210 void KNumber::setDefaultFloatOutput(bool x) 0211 { 0212 detail::knumber_fraction::set_default_fractional_output(!x); 0213 } 0214 0215 //------------------------------------------------------------------------------ 0216 // Name: Pi 0217 //------------------------------------------------------------------------------ 0218 KNumber KNumber::Pi() 0219 { 0220 // TODO: after 4.10 release: 0221 // create a new constructor which works just like the normal QString 0222 // accepting constructor, but allows us to specify separator 0223 // characters, this will allow things to be done slightly more 0224 // efficiently 0225 QString s(QStringLiteral("3.141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117068")); 0226 s.replace(QLatin1Char('.'), DecimalSeparator); 0227 return KNumber(s); 0228 } 0229 0230 //------------------------------------------------------------------------------ 0231 // Name: Euler 0232 //------------------------------------------------------------------------------ 0233 KNumber KNumber::Euler() 0234 { 0235 // TODO: after 4.10 release: 0236 // create a new constructor which works just like the normal QString 0237 // accepting constructor, but allows us to specify separator 0238 // characters, this will allow things to be done slightly more 0239 // efficiently 0240 QString s(QStringLiteral("2.7182818284590452353602874713526624977572470936999595749669676277240766303535475945713821785251664274")); 0241 s.replace(QLatin1Char('.'), DecimalSeparator); 0242 return KNumber(s); 0243 } 0244 0245 //------------------------------------------------------------------------------ 0246 // Name: KNumber 0247 //------------------------------------------------------------------------------ 0248 KNumber::KNumber() 0249 : value_(new detail::knumber_integer(0)) 0250 { 0251 } 0252 0253 //------------------------------------------------------------------------------ 0254 // Name: KNumber 0255 //------------------------------------------------------------------------------ 0256 KNumber::KNumber(const QString &s) 0257 : value_(nullptr) 0258 { 0259 const QRegExp special_regex(QLatin1String("^(inf|-inf|nan)$")); 0260 const QRegExp integer_regex(QLatin1String("^[+-]?\\d+$")); 0261 const QRegExp fraction_regex(QLatin1String("^[+-]?\\d+/\\d+$")); 0262 const QRegExp float_regex(QString(QLatin1String(R"(^([+-]?\d*)(%1\d*)?(e([+-]?\d+))?$)")).arg(QRegExp::escape(DecimalSeparator))); 0263 0264 if (special_regex.exactMatch(s)) { 0265 value_ = new detail::knumber_error(s); 0266 } else if (integer_regex.exactMatch(s)) { 0267 value_ = new detail::knumber_integer(s); 0268 } else if (fraction_regex.exactMatch(s)) { 0269 value_ = new detail::knumber_fraction(s); 0270 simplify(); 0271 } else if (float_regex.exactMatch(s)) { 0272 if (detail::knumber_fraction::default_fractional_input) { 0273 const QStringList list = float_regex.capturedTexts(); 0274 if (list.size() == 5) { 0275 const QString ipart = list[1]; 0276 const QString fpart = list[2]; 0277 const int e_val = list[4].toInt(); 0278 0279 QString num = ipart + fpart.mid(1); 0280 QString den = QLatin1String("1") + QString(fpart.size() - 1, QLatin1Char('0')); 0281 0282 if (e_val < 0) { 0283 den = den + QString(::abs(e_val), QLatin1Char('0')); 0284 } else if (e_val > 0) { 0285 num = num + QString(::abs(e_val), QLatin1Char('0')); 0286 } 0287 0288 value_ = new detail::knumber_fraction(QStringLiteral("%1/%2").arg(num, den)); 0289 simplify(); 0290 return; 0291 } 0292 } 0293 0294 // we need to normalize the decimal separator to US style because that's 0295 // the only type that the GMP function accept 0296 QString new_s = s; 0297 new_s.replace(DecimalSeparator, QLatin1String(".")); 0298 0299 value_ = new detail::knumber_float(new_s); 0300 simplify(); 0301 } else { 0302 value_ = new detail::knumber_error(detail::knumber_error::ERROR_UNDEFINED); 0303 } 0304 } 0305 0306 //------------------------------------------------------------------------------ 0307 // Name: KNumber 0308 //------------------------------------------------------------------------------ 0309 KNumber::KNumber(qint32 value) 0310 : value_(new detail::knumber_integer(value)) 0311 { 0312 } 0313 0314 //------------------------------------------------------------------------------ 0315 // Name: KNumber 0316 //------------------------------------------------------------------------------ 0317 KNumber::KNumber(qint64 value) 0318 : value_(new detail::knumber_integer(value)) 0319 { 0320 } 0321 0322 //------------------------------------------------------------------------------ 0323 // Name: KNumber 0324 //------------------------------------------------------------------------------ 0325 KNumber::KNumber(quint32 value) 0326 : value_(new detail::knumber_integer(value)) 0327 { 0328 } 0329 0330 //------------------------------------------------------------------------------ 0331 // Name: KNumber 0332 //------------------------------------------------------------------------------ 0333 KNumber::KNumber(quint64 value) 0334 : value_(new detail::knumber_integer(value)) 0335 { 0336 } 0337 0338 //------------------------------------------------------------------------------ 0339 // Name: KNumber 0340 //------------------------------------------------------------------------------ 0341 KNumber::KNumber(qint64 num, quint64 den) 0342 : value_(new detail::knumber_fraction(num, den)) 0343 { 0344 } 0345 0346 //------------------------------------------------------------------------------ 0347 // Name: KNumber 0348 //------------------------------------------------------------------------------ 0349 KNumber::KNumber(quint64 num, quint64 den) 0350 : value_(new detail::knumber_fraction(num, den)) 0351 { 0352 } 0353 0354 #ifdef HAVE_LONG_DOUBLE 0355 //------------------------------------------------------------------------------ 0356 // Name: KNumber 0357 //------------------------------------------------------------------------------ 0358 KNumber::KNumber(long double value) 0359 : value_(new detail::knumber_float(value)) 0360 { 0361 simplify(); 0362 } 0363 #endif 0364 0365 //------------------------------------------------------------------------------ 0366 // Name: KNumber 0367 //------------------------------------------------------------------------------ 0368 KNumber::KNumber(double value) 0369 : value_(new detail::knumber_float(value)) 0370 { 0371 simplify(); 0372 } 0373 0374 //------------------------------------------------------------------------------ 0375 // Name: KNumber 0376 //------------------------------------------------------------------------------ 0377 KNumber::KNumber(const KNumber &other) 0378 : value_(nullptr) 0379 { 0380 if (&other != this) { 0381 value_ = other.value_->clone(); 0382 } 0383 } 0384 0385 //------------------------------------------------------------------------------ 0386 // Name: ~KNumber 0387 //------------------------------------------------------------------------------ 0388 KNumber::~KNumber() 0389 { 0390 delete value_; 0391 } 0392 0393 //------------------------------------------------------------------------------ 0394 // Name: type 0395 //------------------------------------------------------------------------------ 0396 KNumber::Type KNumber::type() const 0397 { 0398 if (dynamic_cast<detail::knumber_integer *>(value_)) { 0399 return TYPE_INTEGER; 0400 } else if (dynamic_cast<detail::knumber_float *>(value_)) { 0401 return TYPE_FLOAT; 0402 } else if (dynamic_cast<detail::knumber_fraction *>(value_)) { 0403 return TYPE_FRACTION; 0404 } else if (dynamic_cast<detail::knumber_error *>(value_)) { 0405 return TYPE_ERROR; 0406 } else { 0407 Q_ASSERT(0); 0408 return TYPE_ERROR; 0409 } 0410 } 0411 0412 //------------------------------------------------------------------------------ 0413 // Name: operator= 0414 //------------------------------------------------------------------------------ 0415 KNumber &KNumber::operator=(const KNumber &rhs) 0416 { 0417 KNumber(rhs).swap(*this); 0418 return *this; 0419 } 0420 0421 //------------------------------------------------------------------------------ 0422 // Name: swap 0423 //------------------------------------------------------------------------------ 0424 void KNumber::swap(KNumber &other) 0425 { 0426 qSwap(value_, other.value_); 0427 } 0428 0429 //------------------------------------------------------------------------------ 0430 // Name: integerPart 0431 //------------------------------------------------------------------------------ 0432 KNumber KNumber::integerPart() const 0433 { 0434 KNumber x(*this); 0435 0436 if (auto const p = dynamic_cast<detail::knumber_integer *>(value_)) { 0437 // NO-OP 0438 Q_UNUSED(p); 0439 } else if (auto const p = dynamic_cast<detail::knumber_float *>(value_)) { 0440 detail::knumber_base *v = new detail::knumber_integer(p); 0441 qSwap(v, x.value_); 0442 delete v; 0443 } else if (auto const p = dynamic_cast<detail::knumber_fraction *>(value_)) { 0444 detail::knumber_base *v = new detail::knumber_integer(p); 0445 qSwap(v, x.value_); 0446 delete v; 0447 } else if (auto const p = dynamic_cast<detail::knumber_error *>(value_)) { 0448 // NO-OP 0449 Q_UNUSED(p); 0450 } else { 0451 Q_ASSERT(0); 0452 } 0453 0454 return x; 0455 } 0456 0457 //------------------------------------------------------------------------------ 0458 // Name: simplify 0459 //------------------------------------------------------------------------------ 0460 void KNumber::simplify() 0461 { 0462 if (value_->is_integer()) { 0463 if (auto const p = dynamic_cast<detail::knumber_integer *>(value_)) { 0464 // NO-OP 0465 Q_UNUSED(p); 0466 } else if (auto const p = dynamic_cast<detail::knumber_float *>(value_)) { 0467 detail::knumber_base *v = new detail::knumber_integer(p); 0468 qSwap(v, value_); 0469 delete v; 0470 } else if (auto const p = dynamic_cast<detail::knumber_fraction *>(value_)) { 0471 detail::knumber_base *v = new detail::knumber_integer(p); 0472 qSwap(v, value_); 0473 delete v; 0474 } else if (auto const p = dynamic_cast<detail::knumber_error *>(value_)) { 0475 // NO-OP 0476 Q_UNUSED(p); 0477 } else { 0478 Q_ASSERT(0); 0479 } 0480 } 0481 } 0482 0483 //------------------------------------------------------------------------------ 0484 // Name: operator+= 0485 //------------------------------------------------------------------------------ 0486 KNumber &KNumber::operator+=(const KNumber &rhs) 0487 { 0488 value_ = value_->add(rhs.value_); 0489 simplify(); 0490 return *this; 0491 } 0492 0493 //------------------------------------------------------------------------------ 0494 // Name: operator-= 0495 //------------------------------------------------------------------------------ 0496 KNumber &KNumber::operator-=(const KNumber &rhs) 0497 { 0498 value_ = value_->sub(rhs.value_); 0499 simplify(); 0500 return *this; 0501 } 0502 0503 //------------------------------------------------------------------------------ 0504 // Name: operator*= 0505 //------------------------------------------------------------------------------ 0506 KNumber &KNumber::operator*=(const KNumber &rhs) 0507 { 0508 value_ = value_->mul(rhs.value_); 0509 simplify(); 0510 return *this; 0511 } 0512 0513 //------------------------------------------------------------------------------ 0514 // Name: operator/= 0515 //------------------------------------------------------------------------------ 0516 KNumber &KNumber::operator/=(const KNumber &rhs) 0517 { 0518 // Fix for bug #330577, x/0 is undefined, not infinity 0519 // Also indirectly fixes bug #329897, tan(90) is undefined, not infinity 0520 if (rhs == Zero) { 0521 *this = NaN; 0522 return *this; 0523 } 0524 0525 value_ = value_->div(rhs.value_); 0526 simplify(); 0527 return *this; 0528 } 0529 0530 //------------------------------------------------------------------------------ 0531 // Name: operator%= 0532 //------------------------------------------------------------------------------ 0533 KNumber &KNumber::operator%=(const KNumber &rhs) 0534 { 0535 value_ = value_->mod(rhs.value_); 0536 simplify(); 0537 return *this; 0538 } 0539 0540 //------------------------------------------------------------------------------ 0541 // Name: operator&= 0542 //------------------------------------------------------------------------------ 0543 KNumber &KNumber::operator&=(const KNumber &rhs) 0544 { 0545 value_ = value_->bitwise_and(rhs.value_); 0546 return *this; 0547 } 0548 0549 //------------------------------------------------------------------------------ 0550 // Name: operator|= 0551 //------------------------------------------------------------------------------ 0552 KNumber &KNumber::operator|=(const KNumber &rhs) 0553 { 0554 value_ = value_->bitwise_or(rhs.value_); 0555 return *this; 0556 } 0557 0558 //------------------------------------------------------------------------------ 0559 // Name: operator^= 0560 //------------------------------------------------------------------------------ 0561 KNumber &KNumber::operator^=(const KNumber &rhs) 0562 { 0563 value_ = value_->bitwise_xor(rhs.value_); 0564 return *this; 0565 } 0566 0567 //------------------------------------------------------------------------------ 0568 // Name: operator<< 0569 //------------------------------------------------------------------------------ 0570 KNumber &KNumber::operator<<=(const KNumber &rhs) 0571 { 0572 value_ = value_->bitwise_shift(rhs.value_); 0573 return *this; 0574 } 0575 0576 //------------------------------------------------------------------------------ 0577 // Name: operator>>= 0578 //------------------------------------------------------------------------------ 0579 KNumber &KNumber::operator>>=(const KNumber &rhs) 0580 { 0581 const KNumber rhs_neg(-rhs); 0582 value_ = value_->bitwise_shift(rhs_neg.value_); 0583 return *this; 0584 } 0585 0586 //------------------------------------------------------------------------------ 0587 // Name: operator- 0588 //------------------------------------------------------------------------------ 0589 KNumber KNumber::operator-() const 0590 { 0591 KNumber x(*this); 0592 x.value_ = x.value_->neg(); 0593 return x; 0594 } 0595 0596 //------------------------------------------------------------------------------ 0597 // Name: operator~ 0598 //------------------------------------------------------------------------------ 0599 KNumber KNumber::operator~() const 0600 { 0601 KNumber x(*this); 0602 x.value_ = x.value_->cmp(); 0603 return x; 0604 } 0605 0606 //------------------------------------------------------------------------------ 0607 // Name: toQString 0608 //------------------------------------------------------------------------------ 0609 QString KNumber::toQString(int width, int precision) const 0610 { 0611 if (value_->is_zero()) { 0612 return QStringLiteral("0"); 0613 } 0614 0615 QString s; 0616 0617 if (auto const p = dynamic_cast<detail::knumber_integer *>(value_)) { 0618 if (width > 0) { 0619 s = detail::knumber_float(p).toString(width); 0620 } else { 0621 s = value_->toString(width); 0622 } 0623 } else if (dynamic_cast<detail::knumber_float *>(value_)) { 0624 if (width > 0) { 0625 s = value_->toString(width); 0626 } else { 0627 s = value_->toString(3 * mpf_get_default_prec() / 10); 0628 } 0629 } else if (dynamic_cast<detail::knumber_fraction *>(value_)) { 0630 s = value_->toString(width); 0631 } else { 0632 return value_->toString(width); 0633 } 0634 0635 // now do some rounding to make sure things are displayed reasonably 0636 if (precision >= 0) { 0637 return round(s, precision); 0638 } else { 0639 return s; 0640 } 0641 } 0642 0643 //------------------------------------------------------------------------------ 0644 // Name: toUint64 0645 //------------------------------------------------------------------------------ 0646 quint64 KNumber::toUint64() const 0647 { 0648 return value_->toUint64(); 0649 } 0650 0651 //------------------------------------------------------------------------------ 0652 // Name: toInt64 0653 //------------------------------------------------------------------------------ 0654 qint64 KNumber::toInt64() const 0655 { 0656 return value_->toInt64(); 0657 } 0658 0659 //------------------------------------------------------------------------------ 0660 // Name: abs 0661 //------------------------------------------------------------------------------ 0662 KNumber KNumber::abs() const 0663 { 0664 KNumber z(*this); 0665 z.value_ = z.value_->abs(); 0666 z.simplify(); 0667 return z; 0668 } 0669 0670 //------------------------------------------------------------------------------ 0671 // Name: cbrt 0672 //------------------------------------------------------------------------------ 0673 KNumber KNumber::cbrt() const 0674 { 0675 KNumber z(*this); 0676 z.value_ = z.value_->cbrt(); 0677 z.simplify(); 0678 return z; 0679 } 0680 0681 //------------------------------------------------------------------------------ 0682 // Name: sqrt 0683 //------------------------------------------------------------------------------ 0684 KNumber KNumber::sqrt() const 0685 { 0686 KNumber z(*this); 0687 z.value_ = z.value_->sqrt(); 0688 z.simplify(); 0689 return z; 0690 } 0691 0692 //------------------------------------------------------------------------------ 0693 // Name: pow 0694 //------------------------------------------------------------------------------ 0695 KNumber KNumber::pow(const KNumber &x) const 0696 { 0697 // Fix for bug #330711, pow(0, -x) was causing crashes 0698 // Fix for bug #330597, pow(0,0) was 1 now it is NaN 0699 // Thanks to Raushan Kumar for identifying the issue and submitting 0700 // patches 0701 if (*this == Zero && x <= Zero) { 0702 return NaN; 0703 } 0704 0705 // if the LHS is a special then we can use this function 0706 // no matter what, cause the result is a special too 0707 if (!dynamic_cast<detail::knumber_error *>(value_)) { 0708 // number much bigger than this tend to crash GMP with 0709 // an abort 0710 if (x > KNumber(QStringLiteral("1000000000"))) { 0711 return PosInfinity; 0712 } 0713 } 0714 0715 KNumber z(*this); 0716 z.value_ = z.value_->pow(x.value_); 0717 z.simplify(); 0718 return z; 0719 } 0720 0721 //------------------------------------------------------------------------------ 0722 // Name: sin 0723 //------------------------------------------------------------------------------ 0724 KNumber KNumber::sin() const 0725 { 0726 KNumber z(*this); 0727 z.value_ = z.value_->sin(); 0728 z.simplify(); 0729 return z; 0730 } 0731 0732 //------------------------------------------------------------------------------ 0733 // Name: cos 0734 //------------------------------------------------------------------------------ 0735 KNumber KNumber::cos() const 0736 { 0737 KNumber z(*this); 0738 z.value_ = z.value_->cos(); 0739 z.simplify(); 0740 return z; 0741 } 0742 0743 //------------------------------------------------------------------------------ 0744 // Name: tan 0745 //------------------------------------------------------------------------------ 0746 KNumber KNumber::tan() const 0747 { 0748 KNumber z(*this); 0749 z.value_ = z.value_->tan(); 0750 z.simplify(); 0751 return z; 0752 } 0753 0754 //------------------------------------------------------------------------------ 0755 // Name: tgamma 0756 //------------------------------------------------------------------------------ 0757 KNumber KNumber::tgamma() const 0758 { 0759 KNumber z(*this); 0760 if (z > KNumber(QStringLiteral("10000000000"))) { 0761 return PosInfinity; 0762 } 0763 z.value_ = z.value_->tgamma(); 0764 z.simplify(); 0765 return z; 0766 } 0767 0768 //------------------------------------------------------------------------------ 0769 // Name: asin 0770 //------------------------------------------------------------------------------ 0771 KNumber KNumber::asin() const 0772 { 0773 KNumber z(*this); 0774 z.value_ = z.value_->asin(); 0775 z.simplify(); 0776 return z; 0777 } 0778 0779 //------------------------------------------------------------------------------ 0780 // Name: acos 0781 //------------------------------------------------------------------------------ 0782 KNumber KNumber::acos() const 0783 { 0784 KNumber z(*this); 0785 z.value_ = z.value_->acos(); 0786 z.simplify(); 0787 return z; 0788 } 0789 0790 //------------------------------------------------------------------------------ 0791 // Name: atan 0792 //------------------------------------------------------------------------------ 0793 KNumber KNumber::atan() const 0794 { 0795 KNumber z(*this); 0796 z.value_ = z.value_->atan(); 0797 z.simplify(); 0798 return z; 0799 } 0800 0801 //------------------------------------------------------------------------------ 0802 // Name: sinh 0803 //------------------------------------------------------------------------------ 0804 KNumber KNumber::sinh() const 0805 { 0806 KNumber z(*this); 0807 z.value_ = z.value_->sinh(); 0808 z.simplify(); 0809 return z; 0810 } 0811 0812 //------------------------------------------------------------------------------ 0813 // Name: cosh 0814 //------------------------------------------------------------------------------ 0815 KNumber KNumber::cosh() const 0816 { 0817 KNumber z(*this); 0818 z.value_ = z.value_->cosh(); 0819 z.simplify(); 0820 return z; 0821 } 0822 0823 //------------------------------------------------------------------------------ 0824 // Name: tanh 0825 //------------------------------------------------------------------------------ 0826 KNumber KNumber::tanh() const 0827 { 0828 KNumber z(*this); 0829 z.value_ = z.value_->tanh(); 0830 z.simplify(); 0831 return z; 0832 } 0833 0834 //------------------------------------------------------------------------------ 0835 // Name: asinh 0836 //------------------------------------------------------------------------------ 0837 KNumber KNumber::asinh() const 0838 { 0839 KNumber z(*this); 0840 z.value_ = z.value_->asinh(); 0841 z.simplify(); 0842 return z; 0843 } 0844 0845 //------------------------------------------------------------------------------ 0846 // Name: acosh 0847 //------------------------------------------------------------------------------ 0848 KNumber KNumber::acosh() const 0849 { 0850 KNumber z(*this); 0851 z.value_ = z.value_->acosh(); 0852 z.simplify(); 0853 return z; 0854 } 0855 0856 //------------------------------------------------------------------------------ 0857 // Name: atanh 0858 //------------------------------------------------------------------------------ 0859 KNumber KNumber::atanh() const 0860 { 0861 KNumber z(*this); 0862 z.value_ = z.value_->atanh(); 0863 z.simplify(); 0864 return z; 0865 } 0866 0867 //------------------------------------------------------------------------------ 0868 // Name: factorial 0869 //------------------------------------------------------------------------------ 0870 KNumber KNumber::factorial() const 0871 { 0872 KNumber z(*this); 0873 0874 // number much bigger than this tend to crash GMP with 0875 // an abort 0876 if (z > KNumber(QStringLiteral("10000000000"))) { 0877 return PosInfinity; 0878 } 0879 0880 z.value_ = z.value_->factorial(); 0881 z.simplify(); 0882 return z; 0883 } 0884 0885 //------------------------------------------------------------------------------ 0886 // Name: log2 0887 //------------------------------------------------------------------------------ 0888 KNumber KNumber::log2() const 0889 { 0890 KNumber z(*this); 0891 z.value_ = z.value_->log2(); 0892 z.simplify(); 0893 return z; 0894 } 0895 0896 //------------------------------------------------------------------------------ 0897 // Name: log10 0898 //------------------------------------------------------------------------------ 0899 KNumber KNumber::log10() const 0900 { 0901 KNumber z(*this); 0902 z.value_ = z.value_->log10(); 0903 z.simplify(); 0904 return z; 0905 } 0906 0907 //------------------------------------------------------------------------------ 0908 // Name: ln 0909 //------------------------------------------------------------------------------ 0910 KNumber KNumber::ln() const 0911 { 0912 KNumber z(*this); 0913 z.value_ = z.value_->ln(); 0914 z.simplify(); 0915 return z; 0916 } 0917 0918 //------------------------------------------------------------------------------ 0919 // Name: floor 0920 //------------------------------------------------------------------------------ 0921 KNumber KNumber::floor() const 0922 { 0923 KNumber z(*this); 0924 z.value_ = z.value_->floor(); 0925 z.simplify(); 0926 return z; 0927 } 0928 0929 //------------------------------------------------------------------------------ 0930 // Name: ceil 0931 //------------------------------------------------------------------------------ 0932 KNumber KNumber::ceil() const 0933 { 0934 KNumber z(*this); 0935 z.value_ = z.value_->ceil(); 0936 z.simplify(); 0937 return z; 0938 } 0939 0940 //------------------------------------------------------------------------------ 0941 // Name: exp2 0942 //------------------------------------------------------------------------------ 0943 KNumber KNumber::exp2() const 0944 { 0945 KNumber z(*this); 0946 z.value_ = z.value_->exp2(); 0947 z.simplify(); 0948 return z; 0949 } 0950 0951 //------------------------------------------------------------------------------ 0952 // Name: exp10 0953 //------------------------------------------------------------------------------ 0954 KNumber KNumber::exp10() const 0955 { 0956 KNumber z(*this); 0957 z.value_ = z.value_->exp10(); 0958 z.simplify(); 0959 return z; 0960 } 0961 0962 //------------------------------------------------------------------------------ 0963 // Name: exp 0964 //------------------------------------------------------------------------------ 0965 KNumber KNumber::exp() const 0966 { 0967 KNumber z(*this); 0968 z.value_ = z.value_->exp(); 0969 z.simplify(); 0970 return z; 0971 } 0972 0973 //------------------------------------------------------------------------------ 0974 // Name: bin 0975 //------------------------------------------------------------------------------ 0976 KNumber KNumber::bin(const KNumber &x) const 0977 { 0978 KNumber z(*this); 0979 z.value_ = z.value_->bin(x.value_); 0980 z.simplify(); 0981 return z; 0982 }