File indexing completed on 2024-04-21 05:50:03

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