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

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