19 #include <config-kcalc.h>
24 #include <QScopedArrayPointer>
29 double log2(
double x) {
return log(x) / log(2); }
30 double exp2(
double x) {
return exp(x * log(2)); }
31 double exp10(
double x) {
return exp(x * log(10)); }
36 #define isinf(x) ((x) != 0.0 && (x) + (x) == (x))
40 #define isnan(x) ((x) != (x))
45 #ifdef KNUMBER_USE_MPFR
46 const mpfr_rnd_t knumber_float::rounding_mode = MPFR_RNDN;
47 const mpfr_prec_t knumber_float::precision = 1024;
50 template <
double F(
double)>
51 knumber_base *knumber_float::execute_libc_func(
double x) {
52 const double r = F(x);
67 template <
double F(
double,
double)>
68 knumber_base *knumber_float::execute_libc_func(
double x,
double y) {
69 const double r = F(x, y);
90 mpf_set_str(mpf_, s.
toAscii(), 10);
98 Q_ASSERT(!
isinf(value));
99 Q_ASSERT(!
isnan(value));
101 mpf_init_set_d(mpf_, value);
104 #ifdef HAVE_LONG_DOUBLE
110 Q_ASSERT(!
isinf(value));
111 Q_ASSERT(!
isnan(value));
113 mpf_init_set_d(mpf_, value);
131 mpf_init_set(mpf_, value->mpf_);
140 mpf_set_z(mpf_, value->mpz_);
149 mpf_set_q(mpf_, value->mpq_);
176 }
else if(
knumber_float *
const p = dynamic_cast<knumber_float *>(rhs)) {
177 mpf_add(mpf_, mpf_, p->mpf_);
179 }
else if(
knumber_fraction *
const p = dynamic_cast<knumber_fraction *>(rhs)) {
182 }
else if(
knumber_error *
const p = dynamic_cast<knumber_error *>(rhs)) {
200 }
else if(
knumber_float *
const p = dynamic_cast<knumber_float *>(rhs)) {
201 mpf_sub(mpf_, mpf_, p->mpf_);
203 }
else if(
knumber_fraction *
const p = dynamic_cast<knumber_fraction *>(rhs)) {
206 }
else if(
knumber_error *
const p = dynamic_cast<knumber_error *>(rhs)) {
224 }
else if(
knumber_float *
const p = dynamic_cast<knumber_float *>(rhs)) {
225 mpf_mul(mpf_, mpf_, p->mpf_);
227 }
else if(
knumber_fraction *
const p = dynamic_cast<knumber_fraction *>(rhs)) {
230 }
else if(
knumber_error *
const p = dynamic_cast<knumber_error *>(rhs)) {
268 }
else if(
knumber_float *
const p = dynamic_cast<knumber_float *>(rhs)) {
269 mpf_div(mpf_, mpf_, p->mpf_);
271 }
else if(
knumber_fraction *
const p = dynamic_cast<knumber_fraction *>(rhs)) {
274 }
else if(
knumber_error *
const p = dynamic_cast<knumber_error *>(rhs)) {
275 if(p->sign() > 0 || p->sign() < 0) {
382 #ifdef KNUMBER_USE_MPFR
384 mpfr_init_set_f(mpfr, mpf_, rounding_mode);
385 mpfr_sqrt(mpfr, mpfr, rounding_mode);
386 mpfr_get_f(mpf_, mpfr, rounding_mode);
389 mpf_sqrt(mpf_, mpf_);
399 #ifdef KNUMBER_USE_MPFR
401 mpfr_init_set_f(mpfr, mpf_, rounding_mode);
402 mpfr_cbrt(mpfr, mpfr, rounding_mode);
403 mpfr_get_f(mpf_, mpfr, rounding_mode);
406 const double x = mpf_get_d(mpf_);
412 return execute_libc_func< ::pow>(x, 1.0 / 3.0);
414 return execute_libc_func< ::cbrt>(x);
441 #ifdef KNUMBER_USE_MPFR
443 mpfr_init_set_f(mpfr, mpf_, rounding_mode);
444 mpfr_sin(mpfr, mpfr, rounding_mode);
445 mpfr_get_f(mpf_, mpfr, rounding_mode);
449 const double x = mpf_get_d(mpf_);
454 return execute_libc_func< ::sin>(x);
464 #ifdef KNUMBER_USE_MPFR
466 mpfr_init_set_f(mpfr, mpf_, rounding_mode);
467 mpfr_floor(mpfr, mpfr);
468 mpfr_get_f(mpf_, mpfr, rounding_mode);
472 const double x = mpf_get_d(mpf_);
477 return execute_libc_func< ::floor>(x);
486 #ifdef KNUMBER_USE_MPFR
488 mpfr_init_set_f(mpfr, mpf_, rounding_mode);
489 mpfr_ceil(mpfr, mpfr);
490 mpfr_get_f(mpf_, mpfr, rounding_mode);
494 const double x = mpf_get_d(mpf_);
499 return execute_libc_func< ::ceil>(x);
508 #ifdef KNUMBER_USE_MPFR
510 mpfr_init_set_f(mpfr, mpf_, rounding_mode);
511 mpfr_cos(mpfr, mpfr, rounding_mode);
512 mpfr_get_f(mpf_, mpfr, rounding_mode);
516 const double x = mpf_get_d(mpf_);
521 return execute_libc_func< ::cos>(x);
531 #ifdef KNUMBER_USE_MPFR
533 mpfr_init_set_f(mpfr, mpf_, rounding_mode);
534 mpfr_tan(mpfr, mpfr, rounding_mode);
535 mpfr_get_f(mpf_, mpfr, rounding_mode);
539 const double x = mpf_get_d(mpf_);
544 return execute_libc_func< ::tan>(x);
553 if(mpf_cmp_d(mpf_, 1.0) > 0 || mpf_cmp_d(mpf_, -1.0) < 0) {
558 #ifdef KNUMBER_USE_MPFR
560 mpfr_init_set_f(mpfr, mpf_, rounding_mode);
561 mpfr_asin(mpfr, mpfr, rounding_mode);
562 mpfr_get_f(mpf_, mpfr, rounding_mode);
566 const double x = mpf_get_d(mpf_);
571 return execute_libc_func< ::asin>(x);
580 if(mpf_cmp_d(mpf_, 1.0) > 0 || mpf_cmp_d(mpf_, -1.0) < 0) {
585 #ifdef KNUMBER_USE_MPFR
587 mpfr_init_set_f(mpfr, mpf_, rounding_mode);
588 mpfr_acos(mpfr, mpfr, rounding_mode);
589 mpfr_get_f(mpf_, mpfr, rounding_mode);
593 const double x = mpf_get_d(mpf_);
598 return execute_libc_func< ::acos>(x);
608 #ifdef KNUMBER_USE_MPFR
610 mpfr_init_set_f(mpfr, mpf_, rounding_mode);
611 mpfr_atan(mpfr, mpfr, rounding_mode);
612 mpfr_get_f(mpf_, mpfr, rounding_mode);
616 const double x = mpf_get_d(mpf_);
621 return execute_libc_func< ::atan>(x);
630 #ifdef KNUMBER_USE_MPFR
632 mpfr_init_set_f(mpfr, mpf_, rounding_mode);
633 mpfr_sinh(mpfr, mpfr, rounding_mode);
634 mpfr_get_f(mpf_, mpfr, rounding_mode);
638 const double x = mpf_get_d(mpf_);
639 return execute_libc_func< ::sinh>(x);
648 #ifdef KNUMBER_USE_MPFR
650 mpfr_init_set_f(mpfr, mpf_, rounding_mode);
651 mpfr_cosh(mpfr, mpfr, rounding_mode);
652 mpfr_get_f(mpf_, mpfr, rounding_mode);
656 const double x = mpf_get_d(mpf_);
657 return execute_libc_func< ::cosh>(x);
665 #ifdef KNUMBER_USE_MPFR
667 mpfr_init_set_f(mpfr, mpf_, rounding_mode);
668 mpfr_tanh(mpfr, mpfr, rounding_mode);
669 mpfr_get_f(mpf_, mpfr, rounding_mode);
673 const double x = mpf_get_d(mpf_);
674 return execute_libc_func< ::tanh>(x);
683 #ifdef KNUMBER_USE_MPFR
685 mpfr_init_set_f(mpfr, mpf_, rounding_mode);
686 mpfr_gamma(mpfr, mpfr, rounding_mode);
687 mpfr_get_f(mpf_, mpfr, rounding_mode);
691 const double x = mpf_get_d(mpf_);
697 return execute_libc_func< ::tgamma>(x);
707 #ifdef KNUMBER_USE_MPFR
709 mpfr_init_set_f(mpfr, mpf_, rounding_mode);
710 mpfr_asinh(mpfr, mpfr, rounding_mode);
711 mpfr_get_f(mpf_, mpfr, rounding_mode);
715 const double x = mpf_get_d(mpf_);
716 return execute_libc_func< ::asinh>(x);
724 #ifdef KNUMBER_USE_MPFR
726 mpfr_init_set_f(mpfr, mpf_, rounding_mode);
727 mpfr_acosh(mpfr, mpfr, rounding_mode);
728 mpfr_get_f(mpf_, mpfr, rounding_mode);
732 const double x = mpf_get_d(mpf_);
733 return execute_libc_func< ::acosh>(x);
741 #ifdef KNUMBER_USE_MPFR
743 mpfr_init_set_f(mpfr, mpf_, rounding_mode);
744 mpfr_atanh(mpfr, mpfr, rounding_mode);
745 mpfr_get_f(mpf_, mpfr, rounding_mode);
749 const double x = mpf_get_d(mpf_);
750 return execute_libc_func< ::atanh>(x);
760 mpf_pow_ui(mpf_, mpf_, mpz_get_ui(p->mpz_));
767 }
else if(
knumber_float *
const p = dynamic_cast<knumber_float *>(rhs)) {
768 return execute_libc_func< ::pow>(mpf_get_d(mpf_), mpf_get_d(p->mpf_));
769 }
else if(
knumber_fraction *
const p = dynamic_cast<knumber_fraction *>(rhs)) {
771 return execute_libc_func< ::pow>(mpf_get_d(mpf_), mpf_get_d(f.mpf_));
772 }
else if(
knumber_error *
const p = dynamic_cast<knumber_error *>(rhs)) {
777 }
else if(p->sign() < 0) {
800 }
else if(
knumber_float *
const p = dynamic_cast<knumber_float *>(rhs)) {
801 return mpf_cmp(mpf_, p->mpf_);
802 }
else if(
knumber_fraction *
const p = dynamic_cast<knumber_fraction *>(rhs)) {
805 }
else if(
knumber_error *
const p = dynamic_cast<knumber_error *>(rhs)) {
822 size = gmp_snprintf(NULL, 0,
"%.*Fg", precision, mpf_) + 1;
824 size = gmp_snprintf(NULL, 0,
"%.Fg", mpf_) + 1;
830 gmp_snprintf(&buf[0], size,
"%.*Fg", precision, mpf_);
832 gmp_snprintf(&buf[0], size,
"%.Fg", mpf_);
843 return mpf_integer_p(mpf_) != 0;
851 return mpf_sgn(mpf_) == 0;
859 return mpf_sgn(mpf_);
868 mpf_init_set_d(mpf, 1.0);
869 mpf_div(mpf_, mpf, mpf_);
877 #ifdef KNUMBER_USE_MPFR
879 mpfr_init_set_f(mpfr, mpf_, rounding_mode);
880 mpfr_log2(mpfr, mpfr, rounding_mode);
881 mpfr_get_f(mpf_, mpfr, rounding_mode);
885 const double x = mpf_get_d(mpf_);
890 return execute_libc_func< ::log2>(x);
899 #ifdef KNUMBER_USE_MPFR
901 mpfr_init_set_f(mpfr, mpf_, rounding_mode);
902 mpfr_log10(mpfr, mpfr, rounding_mode);
903 mpfr_get_f(mpf_, mpfr, rounding_mode);
907 const double x = mpf_get_d(mpf_);
912 return execute_libc_func< ::log10>(x);
921 #ifdef KNUMBER_USE_MPFR
923 mpfr_init_set_f(mpfr, mpf_, rounding_mode);
924 mpfr_log(mpfr, mpfr, rounding_mode);
925 mpfr_get_f(mpf_, mpfr, rounding_mode);
929 const double x = mpf_get_d(mpf_);
934 return execute_libc_func< ::log>(x);
943 #ifdef KNUMBER_USE_MPFR
945 mpfr_init_set_f(mpfr, mpf_, rounding_mode);
946 mpfr_exp2(mpfr, mpfr, rounding_mode);
947 mpfr_get_f(mpf_, mpfr, rounding_mode);
951 const double x = mpf_get_d(mpf_);
956 return execute_libc_func< ::exp2>(x);
965 #ifdef KNUMBER_USE_MPFR
967 mpfr_init_set_f(mpfr, mpf_, rounding_mode);
968 mpfr_exp10(mpfr, mpfr, rounding_mode);
969 mpfr_get_f(mpf_, mpfr, rounding_mode);
973 const double x = mpf_get_d(mpf_);
978 return execute_libc_func< ::pow>(10, x);
987 #ifdef KNUMBER_USE_MPFR
989 mpfr_init_set_f(mpfr, mpf_, rounding_mode);
990 mpfr_exp(mpfr, mpfr, rounding_mode);
991 mpfr_get_f(mpf_, mpfr, rounding_mode);
995 const double x = mpf_get_d(mpf_);
1000 return execute_libc_func< ::exp>(x);
virtual knumber_base * cosh()
virtual knumber_base * floor()
virtual knumber_base * tanh()
knumber_float(const QString &s)
virtual knumber_base * atanh()
virtual knumber_base * add(knumber_base *rhs)
virtual knumber_base * sqrt()
virtual knumber_base * tan()
virtual knumber_base * exp10()
virtual knumber_base * mul(knumber_base *rhs)
KNumber exp(const KNumber &x)
friend class knumber_integer
virtual knumber_base * pow(knumber_base *rhs)
virtual knumber_base * cbrt()
virtual qint64 toInt64() const
virtual bool is_zero() const =0
virtual knumber_base * bin(knumber_base *rhs)
virtual knumber_base * sin()
virtual knumber_base * ln()
virtual quint64 toUint64() const
virtual knumber_base * tgamma()
virtual QString toString(int precision) const
KNumber exp2(const KNumber &x)
virtual knumber_base * div(knumber_base *rhs)
virtual knumber_base * factorial()
virtual knumber_base * bitwise_or(knumber_base *rhs)
virtual knumber_base * sub(knumber_base *rhs)
virtual knumber_base * bitwise_xor(knumber_base *rhs)
virtual knumber_base * asinh()
virtual knumber_base * cmp()
virtual knumber_base * exp2()
virtual knumber_base * acos()
virtual knumber_base * mod(knumber_base *rhs)
virtual knumber_base * exp()
virtual knumber_base * reciprocal()
virtual knumber_base * log10()
virtual knumber_base * acosh()
virtual knumber_base * abs()
virtual knumber_base * atan()
virtual knumber_base * cos()
virtual knumber_base * bitwise_shift(knumber_base *rhs)
virtual knumber_base * asin()
virtual int compare(knumber_base *rhs)
friend class knumber_error
virtual knumber_base * clone()
virtual knumber_base * ceil()
virtual knumber_base * neg()
virtual knumber_base * sinh()
virtual bool is_integer() const
virtual knumber_base * log2()
KNumber exp10(const KNumber &x)
virtual knumber_base * factorial()
virtual knumber_base * bitwise_and(knumber_base *rhs)
virtual bool is_zero() const
KNumber log2(const KNumber &x)
virtual knumber_base * neg()
QByteArray toAscii() const