File indexing completed on 2024-05-12 04:45:53

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