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) {
381 #ifdef KNUMBER_USE_MPFR
383 mpfr_init_set_f(mpfr, mpf_, rounding_mode);
384 mpfr_sqrt(mpfr, mpfr, rounding_mode);
385 mpfr_get_f(mpf_, mpfr, rounding_mode);
388 mpf_sqrt(mpf_, mpf_);
398 #ifdef KNUMBER_USE_MPFR
400 mpfr_init_set_f(mpfr, mpf_, rounding_mode);
401 mpfr_cbrt(mpfr, mpfr, rounding_mode);
402 mpfr_get_f(mpf_, mpfr, rounding_mode);
405 const double x = mpf_get_d(mpf_);
411 return execute_libc_func< ::pow>(x, 1.0 / 3.0);
413 return execute_libc_func< ::cbrt>(x);
440 #ifdef KNUMBER_USE_MPFR
442 mpfr_init_set_f(mpfr, mpf_, rounding_mode);
443 mpfr_sin(mpfr, mpfr, rounding_mode);
444 mpfr_get_f(mpf_, mpfr, rounding_mode);
448 const double x = mpf_get_d(mpf_);
453 return execute_libc_func< ::sin>(x);
464 #ifdef KNUMBER_USE_MPFR
466 mpfr_init_set_f(mpfr, mpf_, rounding_mode);
467 mpfr_cos(mpfr, mpfr, rounding_mode);
468 mpfr_get_f(mpf_, mpfr, rounding_mode);
472 const double x = mpf_get_d(mpf_);
477 return execute_libc_func< ::cos>(x);
487 #ifdef KNUMBER_USE_MPFR
489 mpfr_init_set_f(mpfr, mpf_, rounding_mode);
490 mpfr_tan(mpfr, mpfr, rounding_mode);
491 mpfr_get_f(mpf_, mpfr, rounding_mode);
495 const double x = mpf_get_d(mpf_);
500 return execute_libc_func< ::tan>(x);
509 if(mpf_cmp_d(mpf_, 1.0) > 0 || mpf_cmp_d(mpf_, -1.0) < 0) {
514 #ifdef KNUMBER_USE_MPFR
516 mpfr_init_set_f(mpfr, mpf_, rounding_mode);
517 mpfr_asin(mpfr, mpfr, rounding_mode);
518 mpfr_get_f(mpf_, mpfr, rounding_mode);
522 const double x = mpf_get_d(mpf_);
527 return execute_libc_func< ::asin>(x);
536 if(mpf_cmp_d(mpf_, 1.0) > 0 || mpf_cmp_d(mpf_, -1.0) < 0) {
541 #ifdef KNUMBER_USE_MPFR
543 mpfr_init_set_f(mpfr, mpf_, rounding_mode);
544 mpfr_acos(mpfr, mpfr, rounding_mode);
545 mpfr_get_f(mpf_, mpfr, rounding_mode);
549 const double x = mpf_get_d(mpf_);
554 return execute_libc_func< ::acos>(x);
564 #ifdef KNUMBER_USE_MPFR
566 mpfr_init_set_f(mpfr, mpf_, rounding_mode);
567 mpfr_atan(mpfr, mpfr, rounding_mode);
568 mpfr_get_f(mpf_, mpfr, rounding_mode);
572 const double x = mpf_get_d(mpf_);
577 return execute_libc_func< ::atan>(x);
586 #ifdef KNUMBER_USE_MPFR
588 mpfr_init_set_f(mpfr, mpf_, rounding_mode);
589 mpfr_sinh(mpfr, mpfr, rounding_mode);
590 mpfr_get_f(mpf_, mpfr, rounding_mode);
594 const double x = mpf_get_d(mpf_);
595 return execute_libc_func< ::sinh>(x);
604 #ifdef KNUMBER_USE_MPFR
606 mpfr_init_set_f(mpfr, mpf_, rounding_mode);
607 mpfr_cosh(mpfr, mpfr, rounding_mode);
608 mpfr_get_f(mpf_, mpfr, rounding_mode);
612 const double x = mpf_get_d(mpf_);
613 return execute_libc_func< ::cosh>(x);
621 #ifdef KNUMBER_USE_MPFR
623 mpfr_init_set_f(mpfr, mpf_, rounding_mode);
624 mpfr_tanh(mpfr, mpfr, rounding_mode);
625 mpfr_get_f(mpf_, mpfr, rounding_mode);
629 const double x = mpf_get_d(mpf_);
630 return execute_libc_func< ::tanh>(x);
638 #ifdef KNUMBER_USE_MPFR
640 mpfr_init_set_f(mpfr, mpf_, rounding_mode);
641 mpfr_asinh(mpfr, mpfr, rounding_mode);
642 mpfr_get_f(mpf_, mpfr, rounding_mode);
646 const double x = mpf_get_d(mpf_);
647 return execute_libc_func< ::asinh>(x);
655 #ifdef KNUMBER_USE_MPFR
657 mpfr_init_set_f(mpfr, mpf_, rounding_mode);
658 mpfr_acosh(mpfr, mpfr, rounding_mode);
659 mpfr_get_f(mpf_, mpfr, rounding_mode);
663 const double x = mpf_get_d(mpf_);
664 return execute_libc_func< ::acosh>(x);
672 #ifdef KNUMBER_USE_MPFR
674 mpfr_init_set_f(mpfr, mpf_, rounding_mode);
675 mpfr_atanh(mpfr, mpfr, rounding_mode);
676 mpfr_get_f(mpf_, mpfr, rounding_mode);
680 const double x = mpf_get_d(mpf_);
681 return execute_libc_func< ::atanh>(x);
691 mpf_pow_ui(mpf_, mpf_, mpz_get_ui(p->mpz_));
698 }
else if(
knumber_float *
const p = dynamic_cast<knumber_float *>(rhs)) {
699 return execute_libc_func< ::pow>(mpf_get_d(mpf_), mpf_get_d(p->mpf_));
700 }
else if(
knumber_fraction *
const p = dynamic_cast<knumber_fraction *>(rhs)) {
702 return execute_libc_func< ::pow>(mpf_get_d(mpf_), mpf_get_d(f.mpf_));
703 }
else if(
knumber_error *
const p = dynamic_cast<knumber_error *>(rhs)) {
708 }
else if(p->sign() < 0) {
731 }
else if(
knumber_float *
const p = dynamic_cast<knumber_float *>(rhs)) {
732 return mpf_cmp(mpf_, p->mpf_);
733 }
else if(
knumber_fraction *
const p = dynamic_cast<knumber_fraction *>(rhs)) {
736 }
else if(
knumber_error *
const p = dynamic_cast<knumber_error *>(rhs)) {
753 size = gmp_snprintf(NULL, 0,
"%.*Fg", precision, mpf_) + 1;
755 size = gmp_snprintf(NULL, 0,
"%.Fg", mpf_) + 1;
758 QScopedArrayPointer<char> buf(
new char[size]);
761 gmp_snprintf(&buf[0], size,
"%.*Fg", precision, mpf_);
763 gmp_snprintf(&buf[0], size,
"%.Fg", mpf_);
766 return QLatin1String(&buf[0]);
774 return mpf_integer_p(mpf_) != 0;
782 return mpf_sgn(mpf_) == 0;
790 return mpf_sgn(mpf_);
799 mpf_init_set_d(mpf, 1.0);
800 mpf_div(mpf_, mpf, mpf_);
808 #ifdef KNUMBER_USE_MPFR
810 mpfr_init_set_f(mpfr, mpf_, rounding_mode);
811 mpfr_log2(mpfr, mpfr, rounding_mode);
812 mpfr_get_f(mpf_, mpfr, rounding_mode);
816 const double x = mpf_get_d(mpf_);
821 return execute_libc_func< ::log2>(x);
830 #ifdef KNUMBER_USE_MPFR
832 mpfr_init_set_f(mpfr, mpf_, rounding_mode);
833 mpfr_log10(mpfr, mpfr, rounding_mode);
834 mpfr_get_f(mpf_, mpfr, rounding_mode);
838 const double x = mpf_get_d(mpf_);
843 return execute_libc_func< ::log10>(x);
852 #ifdef KNUMBER_USE_MPFR
854 mpfr_init_set_f(mpfr, mpf_, rounding_mode);
855 mpfr_log(mpfr, mpfr, rounding_mode);
856 mpfr_get_f(mpf_, mpfr, rounding_mode);
860 const double x = mpf_get_d(mpf_);
865 return execute_libc_func< ::log>(x);
874 #ifdef KNUMBER_USE_MPFR
876 mpfr_init_set_f(mpfr, mpf_, rounding_mode);
877 mpfr_exp2(mpfr, mpfr, rounding_mode);
878 mpfr_get_f(mpf_, mpfr, rounding_mode);
882 const double x = mpf_get_d(mpf_);
887 return execute_libc_func< ::exp2>(x);
896 #ifdef KNUMBER_USE_MPFR
898 mpfr_init_set_f(mpfr, mpf_, rounding_mode);
899 mpfr_exp10(mpfr, mpfr, rounding_mode);
900 mpfr_get_f(mpf_, mpfr, rounding_mode);
904 const double x = mpf_get_d(mpf_);
909 return execute_libc_func< ::pow>(10, x);
918 #ifdef KNUMBER_USE_MPFR
920 mpfr_init_set_f(mpfr, mpf_, rounding_mode);
921 mpfr_exp(mpfr, mpfr, rounding_mode);
922 mpfr_get_f(mpf_, mpfr, rounding_mode);
926 const double x = mpf_get_d(mpf_);
931 return execute_libc_func< ::exp>(x);
virtual knumber_base * cosh()
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 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 * 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()