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 }