29#include "knumber_priv.h"
31_knumerror::_knumerror(_knumber
const & num)
35 _error =
dynamic_cast<_knumerror
const &
>(num)._error;
47_knuminteger::_knuminteger(
unsigned long long int num)
50#if SIZEOF_UNSIGNED_LONG == 8
51 mpz_init_set_ui(_mpz,
static_cast<unsigned long int>(num));
52#elif SIZEOF_UNSIGNED_LONG == 4
53 mpz_set_ui(_mpz,
static_cast<unsigned long int>(num >> 32));
54 mpz_mul_2exp(_mpz, _mpz, 32);
55 mpz_add_ui(_mpz, _mpz,
static_cast<unsigned long int>(num));
57#error "SIZEOF_UNSIGNED_LONG is a unhandled case"
62_knuminteger::_knuminteger(_knumber
const & num)
68 mpz_set(_mpz,
dynamic_cast<_knuminteger
const &
>(num)._mpz);
78_knumfraction::_knumfraction(_knumber
const & num)
84 mpq_set_z(_mpq,
dynamic_cast<_knuminteger
const &
>(num)._mpz);
87 mpq_set(_mpq,
dynamic_cast<_knumfraction
const &
>(num)._mpq);
96_knumfloat::_knumfloat(_knumber
const & num)
102 mpf_set_z(_mpf,
dynamic_cast<_knuminteger
const &
>(num)._mpz);
105 mpf_set_q(_mpf,
dynamic_cast<_knumfraction
const &
>(num)._mpq);
108 mpf_set(_mpf,
dynamic_cast<_knumfloat
const &
>(num)._mpf);
118_knumerror::_knumerror(TQString
const & num)
121 _error = UndefinedNumber;
122 else if (num ==
"inf")
124 else if (num ==
"-inf")
125 _error = MinusInfinity;
128_knuminteger::_knuminteger(TQString
const & num)
131 mpz_set_str(_mpz, num.ascii(), 10);
134_knumfraction::_knumfraction(TQString
const & num)
137 if (TQRegExp(
"^[+-]?\\d+(\\.\\d*)?(e[+-]?\\d+)?$").exactMatch(num)) {
140 unsigned long int digits_after_dot = ((num.section(
'.', 1, 1)).section(
'e', 0, 0)).length();
141 TQString tmp_num = num.section(
'e', 0, 0).remove(
'.');
142 mpq_set_str(_mpq, tmp_num.ascii(), 10);
145 mpz_ui_pow_ui (tmp_int, 10, digits_after_dot);
146 mpz_mul(mpq_denref(_mpq), mpq_denref(_mpq), tmp_int);
148 if (! (tmp_num = num.section(
'e', 1, 1)).isEmpty()) {
149 long int tmp_exp = tmp_num.toLong();
151 mpz_ui_pow_ui (tmp_int, 10,
152 static_cast<unsigned long int>(tmp_exp));
153 mpz_mul(mpq_numref(_mpq), mpq_numref(_mpq), tmp_int);
155 mpz_ui_pow_ui (tmp_int, 10,
156 static_cast<unsigned long int>(-tmp_exp));
157 mpz_mul(mpq_denref(_mpq), mpq_denref(_mpq), tmp_int);
162 mpq_set_str(_mpq, num.ascii(), 10);
163 mpq_canonicalize(_mpq);
166_knumfloat::_knumfloat(TQString
const & num)
169 mpf_set_str(_mpf, num.ascii(), 10);
172_knuminteger
const & _knuminteger::operator = (_knuminteger
const & num)
177 mpz_set(_mpz, num._mpz);
181TQString
const _knumerror::ascii(
int prec)
const
183 static_cast<void>(prec);
186 case UndefinedNumber:
187 return TQString(
"nan");
189 return TQString(
"inf");
191 return TQString(
"-inf");
197TQString
const _knuminteger::ascii(
int prec)
const
199 static_cast<void>(prec);
202 gmp_asprintf(&tmp_ptr,
"%Zd", _mpz);
203 TQString ret_str = tmp_ptr;
209TQString
const _knumfraction::ascii(
int prec)
const
211 static_cast<void>(prec);
212 char *tmp_ptr = mpq_get_str(0, 10, _mpq);
213 TQString ret_str = tmp_ptr;
220TQString
const _knumfloat::ascii(
int prec)
const
225 gmp_asprintf(&tmp_ptr, (
"%." + TQString(TQString().setNum(prec) +
"Fg")).ascii(), _mpf);
227 gmp_asprintf(&tmp_ptr,
"%Fg", _mpf);
237bool _knumfraction::isInteger(
void)
const
239 if (mpz_cmp_ui(mpq_denref(_mpq), 1) == 0)
246_knumber * _knumerror::abs(
void)
const
248 _knumerror * tmp_num =
new _knumerror(*
this);
250 if(_error == MinusInfinity) tmp_num->_error = Infinity;
255_knumber * _knuminteger::abs(
void)
const
257 _knuminteger * tmp_num =
new _knuminteger();
259 mpz_abs(tmp_num->_mpz, _mpz);
264_knumber * _knumfraction::abs(
void)
const
266 _knumfraction * tmp_num =
new _knumfraction();
268 mpq_abs(tmp_num->_mpq, _mpq);
273_knumber * _knumfloat::abs(
void)
const
275 _knumfloat * tmp_num =
new _knumfloat();
277 mpf_abs(tmp_num->_mpf, _mpf);
284_knumber * _knumerror::intPart(
void)
const
286 return new _knumerror(*
this);
289_knumber * _knuminteger::intPart(
void)
const
291 _knuminteger *tmp_num =
new _knuminteger();
292 mpz_set(tmp_num->_mpz, _mpz);
296_knumber * _knumfraction::intPart(
void)
const
298 _knuminteger *tmp_num =
new _knuminteger();
300 mpz_set_q(tmp_num->_mpz, _mpq);
305_knumber * _knumfloat::intPart(
void)
const
307 _knuminteger *tmp_num =
new _knuminteger();
309 mpz_set_f(tmp_num->_mpz, _mpf);
317int _knumerror::sign(
void)
const
329int _knuminteger::sign(
void)
const
331 return mpz_sgn(_mpz);
334int _knumfraction::sign(
void)
const
336 return mpq_sgn(_mpq);
339int _knumfloat::sign(
void)
const
341 return mpf_sgn(_mpf);
346#warning _cbrt for now this is a stupid work around
347static void _cbrt(mpf_t &num)
349 double tmp_num = cbrt(mpf_get_d(num));
350 mpf_init_set_d(num, tmp_num);
354_knumber * _knumerror::cbrt(
void)
const
357 _knumerror *tmp_num =
new _knumerror(*
this);
362_knumber * _knuminteger::cbrt(
void)
const
364 _knuminteger * tmp_num =
new _knuminteger();
366 if(mpz_root(tmp_num->_mpz, _mpz, 3))
371 _knumfloat * tmp_num2 =
new _knumfloat();
372 mpf_set_z(tmp_num2->_mpf, _mpz);
374 _cbrt(tmp_num2->_mpf);
379_knumber * _knumfraction::cbrt(
void)
const
381 _knumfraction * tmp_num =
new _knumfraction();
382 if (mpz_root(mpq_numref(tmp_num->_mpq), mpq_numref(_mpq), 3)
383 && mpz_root(mpq_denref(tmp_num->_mpq), mpq_denref(_mpq), 3))
388 _knumfloat * tmp_num2 =
new _knumfloat();
389 mpf_set_q(tmp_num2->_mpf, _mpq);
391 _cbrt(tmp_num2->_mpf);
396_knumber * _knumfloat::cbrt(
void)
const
398 _knumfloat * tmp_num =
new _knumfloat(*
this);
400 _cbrt(tmp_num->_mpf);
408_knumber * _knumerror::sqrt(
void)
const
410 _knumerror *tmp_num =
new _knumerror(*
this);
412 if(_error == MinusInfinity) tmp_num->_error = UndefinedNumber;
417_knumber * _knuminteger::sqrt(
void)
const
419 if (mpz_sgn(_mpz) < 0) {
420 _knumerror *tmp_num =
new _knumerror(UndefinedNumber);
423 if (mpz_perfect_square_p(_mpz)) {
424 _knuminteger * tmp_num =
new _knuminteger();
426 mpz_sqrt(tmp_num->_mpz, _mpz);
430 _knumfloat * tmp_num =
new _knumfloat();
431 mpf_set_z(tmp_num->_mpf, _mpz);
432 mpf_sqrt(tmp_num->_mpf, tmp_num->_mpf);
438_knumber * _knumfraction::sqrt(
void)
const
440 if (mpq_sgn(_mpq) < 0) {
441 _knumerror *tmp_num =
new _knumerror(UndefinedNumber);
444 if (mpz_perfect_square_p(mpq_numref(_mpq))
445 && mpz_perfect_square_p(mpq_denref(_mpq))) {
446 _knumfraction * tmp_num =
new _knumfraction();
447 mpq_set(tmp_num->_mpq, _mpq);
448 mpz_sqrt(mpq_numref(tmp_num->_mpq), mpq_numref(tmp_num->_mpq));
449 mpz_sqrt(mpq_denref(tmp_num->_mpq), mpq_denref(tmp_num->_mpq));
453 _knumfloat * tmp_num =
new _knumfloat();
454 mpf_set_q(tmp_num->_mpf, _mpq);
455 mpf_sqrt(tmp_num->_mpf, tmp_num->_mpf);
460 _knumfraction * tmp_num =
new _knumfraction();
465_knumber * _knumfloat::sqrt(
void)
const
467 if (mpf_sgn(_mpf) < 0) {
468 _knumerror *tmp_num =
new _knumerror(UndefinedNumber);
471 _knumfloat * tmp_num =
new _knumfloat();
473 mpf_sqrt(tmp_num->_mpf, _mpf);
480_knumber * _knumerror::change_sign(
void)
const
482 _knumerror * tmp_num =
new _knumerror();
484 if(_error == Infinity) tmp_num->_error = MinusInfinity;
485 if(_error == MinusInfinity) tmp_num->_error = Infinity;
490_knumber * _knuminteger::change_sign(
void)
const
492 _knuminteger * tmp_num =
new _knuminteger();
494 mpz_neg(tmp_num->_mpz, _mpz);
499_knumber * _knumfraction::change_sign(
void)
const
501 _knumfraction * tmp_num =
new _knumfraction();
503 mpq_neg(tmp_num->_mpq, _mpq);
508_knumber *_knumfloat::change_sign(
void)
const
510 _knumfloat * tmp_num =
new _knumfloat();
512 mpf_neg(tmp_num->_mpf, _mpf);
518_knumber * _knumerror::reciprocal(
void)
const
523 return new _knuminteger(0);
524 case UndefinedNumber:
526 return new _knumerror(UndefinedNumber);
530_knumber * _knuminteger::reciprocal(
void)
const
532 if(mpz_cmp_si(_mpz, 0) == 0)
return new _knumerror(Infinity);
534 _knumfraction * tmp_num =
new _knumfraction(*
this);
536 mpq_inv(tmp_num->_mpq, tmp_num->_mpq);
541_knumber * _knumfraction::reciprocal()
const
543 if(mpq_cmp_si(_mpq, 0, 1) == 0)
return new _knumerror(Infinity);
545 _knumfraction * tmp_num =
new _knumfraction();
547 mpq_inv(tmp_num->_mpq, _mpq);
552_knumber *_knumfloat::reciprocal(
void)
const
554 if(mpf_cmp_si(_mpf, 0) == 0)
return new _knumerror(Infinity);
556 _knumfloat * tmp_num =
new _knumfloat();
558 mpf_div(tmp_num->_mpf, _knumfloat(
"1.0")._mpf, _mpf);
565_knumber * _knumerror::add(_knumber
const & arg2)
const
567 if (arg2.type() != SpecialType)
568 return new _knumerror(_error);
570 _knumerror
const & tmp_arg2 =
dynamic_cast<_knumerror
const &
>(arg2);
572 if (_error == UndefinedNumber
573 || tmp_arg2._error == UndefinedNumber
574 || (_error == Infinity && tmp_arg2._error == MinusInfinity)
575 || (_error == MinusInfinity && tmp_arg2._error == Infinity)
577 return new _knumerror(UndefinedNumber);
579 return new _knumerror(_error);
582_knumber * _knuminteger::add(_knumber
const & arg2)
const
584 if (arg2.type() != IntegerType)
585 return arg2.add(*
this);
587 _knuminteger * tmp_num =
new _knuminteger();
589 mpz_add(tmp_num->_mpz, _mpz,
590 dynamic_cast<_knuminteger
const &
>(arg2)._mpz);
595_knumber * _knumfraction::add(_knumber
const & arg2)
const
597 if (arg2.type() == IntegerType) {
599 _knumfraction tmp_num(arg2);
600 return tmp_num.add(*
this);
604 if (arg2.type() == FloatType || arg2.type() == SpecialType)
605 return arg2.add(*
this);
607 _knumfraction * tmp_num =
new _knumfraction();
609 mpq_add(tmp_num->_mpq, _mpq,
610 dynamic_cast<_knumfraction
const &
>(arg2)._mpq);
615_knumber *_knumfloat::add(_knumber
const & arg2)
const
617 if (arg2.type() == SpecialType)
618 return arg2.add(*
this);
620 if (arg2.type() != FloatType) {
622 _knumfloat tmp_num(arg2);
623 return tmp_num.add(*
this);
626 _knumfloat * tmp_num =
new _knumfloat();
628 mpf_add(tmp_num->_mpf, _mpf,
629 dynamic_cast<_knumfloat
const &
>(arg2)._mpf);
635_knumber * _knumerror::multiply(_knumber
const & arg2)
const
638 switch(arg2.type()) {
641 _knumerror
const & tmp_arg2 =
dynamic_cast<_knumerror
const &
>(arg2);
642 if (_error == UndefinedNumber || tmp_arg2._error == UndefinedNumber)
643 return new _knumerror(UndefinedNumber);
644 if ( this->sign() * arg2.sign() > 0)
645 return new _knumerror(Infinity);
647 return new _knumerror(MinusInfinity);
653 int sign_arg2 = arg2.sign();
654 if (_error == UndefinedNumber || sign_arg2 == 0)
655 return new _knumerror(UndefinedNumber);
656 if ( (_error == Infinity && sign_arg2 > 0) ||
657 (_error == MinusInfinity && sign_arg2 < 0) )
658 return new _knumerror(Infinity);
660 return new _knumerror(MinusInfinity);
664 return new _knumerror(_error);
668_knumber * _knuminteger::multiply(_knumber
const & arg2)
const
670 if (arg2.type() != IntegerType)
671 return arg2.multiply(*
this);
673 _knuminteger * tmp_num =
new _knuminteger();
675 mpz_mul(tmp_num->_mpz, _mpz,
676 dynamic_cast<_knuminteger
const &
>(arg2)._mpz);
681_knumber * _knumfraction::multiply(_knumber
const & arg2)
const
683 if (arg2.type() == IntegerType) {
685 _knumfraction tmp_num(arg2);
686 return tmp_num.multiply(*
this);
690 if (arg2.type() == FloatType || arg2.type() == SpecialType)
691 return arg2.multiply(*
this);
693 _knumfraction * tmp_num =
new _knumfraction();
695 mpq_mul(tmp_num->_mpq, _mpq,
696 dynamic_cast<_knumfraction
const &
>(arg2)._mpq);
701_knumber *_knumfloat::multiply(_knumber
const & arg2)
const
703 if (arg2.type() == SpecialType)
704 return arg2.multiply(*
this);
705 if (arg2.type() == IntegerType &&
706 mpz_cmp_si(
dynamic_cast<_knuminteger
const &
>(arg2)._mpz,0) == 0)
708 return new _knuminteger(0);
710 if (arg2.type() != FloatType) {
712 _knumfloat tmp_num(arg2);
713 return tmp_num.multiply(*
this);
716 _knumfloat * tmp_num =
new _knumfloat();
718 mpf_mul(tmp_num->_mpf, _mpf,
719 dynamic_cast<_knumfloat
const &
>(arg2)._mpf);
728_knumber * _knumber::divide(_knumber
const & arg2)
const
730 _knumber * tmp_num = arg2.reciprocal();
731 _knumber * rslt_num = this->multiply(*tmp_num);
738_knumber *_knumfloat::divide(_knumber
const & arg2)
const
740 if(mpf_cmp_si(_mpf, 0) == 0)
return new _knumerror(Infinity);
743 _knumfloat * tmp_num =
new _knumfloat(arg2);
745 mpf_div(tmp_num->_mpf, _mpf, tmp_num->_mpf);
753_knumber * _knumerror::power(_knumber
const & exponent)
const
755 static_cast<void>(exponent);
756 return new _knumerror(UndefinedNumber);
759_knumber * _knuminteger::power(_knumber
const & exponent)
const
761 if (exponent.type() == IntegerType) {
764 mpz_init_set(tmp_mpz,
765 dynamic_cast<_knuminteger
const &
>(exponent)._mpz);
767 if (! mpz_fits_ulong_p(tmp_mpz)) {
771 _knumfloat tmp_num1(*
this), tmp_num2(exponent);
772 return tmp_num1.power(tmp_num2);
775 unsigned long int tmp_int = mpz_get_ui(tmp_mpz);
778 _knuminteger * tmp_num =
new _knuminteger();
779 mpz_pow_ui(tmp_num->_mpz, _mpz, tmp_int);
782 if (exponent.type() == FractionType) {
783 if (mpz_sgn(_mpz) < 0)
784 return new _knumerror(UndefinedNumber);
788 mpz_init_set(tmp_mpz,
789 mpq_denref(
dynamic_cast<_knumfraction
const &
>(exponent)._mpq));
791 if (! mpz_fits_ulong_p(tmp_mpz)) {
795 _knumfloat tmp_num1(*
this), tmp_num2(exponent);
796 return tmp_num1.power(tmp_num2);
799 unsigned long int tmp_int = mpz_get_ui(tmp_mpz);
803 _knuminteger * tmp_num =
new _knuminteger();
804 int flag = mpz_root(tmp_num->_mpz, _mpz, tmp_int);
808 _knumfloat tmp_num1(*
this), tmp_num2(exponent);
809 return tmp_num1.power(tmp_num2);
814 mpz_init_set(tmp_mpz,
815 mpq_numref(
dynamic_cast<_knumfraction
const &
>(exponent)._mpq));
817 if (! mpz_fits_ulong_p(tmp_mpz)) {
821 _knumfloat tmp_num1(*
this), tmp_num2(exponent);
822 return tmp_num1.power(tmp_num2);
824 tmp_int = mpz_get_ui(tmp_mpz);
827 mpz_pow_ui(tmp_num->_mpz, tmp_num->_mpz, tmp_int);
831 if (exponent.type() == FloatType) {
833 _knumfloat tmp_num(*
this);
834 return tmp_num.power(exponent);
837 return new _knumerror(Infinity);
840_knumber * _knumfraction::power(_knumber
const & exponent)
const
842 _knuminteger tmp_num = _knuminteger();
844 mpz_set(tmp_num._mpz, mpq_numref(_mpq));
845 _knumber *numer = tmp_num.power(exponent);
847 mpz_set(tmp_num._mpz, mpq_denref(_mpq));
848 _knumber *denom = tmp_num.power(exponent);
850 _knumber *result = numer->divide(*denom);
856_knumber * _knumfloat::power(_knumber
const & exponent)
const
858 return new _knumfloat(pow(
static_cast<double>(*
this),
859 static_cast<double>(exponent)));
863int _knumerror::compare(_knumber
const &arg2)
const
865 if (arg2.type() != SpecialType) {
878 if (
dynamic_cast<_knumerror
const &
>(arg2)._error == Infinity)
883 if (
dynamic_cast<_knumerror
const &
>(arg2)._error == MinusInfinity)
888 if (
dynamic_cast<_knumerror
const &
>(arg2)._error == UndefinedNumber)
891 return -arg2.compare(*
this);
895int _knuminteger::compare(_knumber
const &arg2)
const
897 if (arg2.type() != IntegerType)
898 return - arg2.compare(*
this);
900 return mpz_cmp(_mpz,
dynamic_cast<_knuminteger
const &
>(arg2)._mpz);
903int _knumfraction::compare(_knumber
const &arg2)
const
905 if (arg2.type() != FractionType) {
906 if (arg2.type() == IntegerType) {
910 dynamic_cast<_knuminteger
const &
>(arg2)._mpz);
911 int cmp_result = mpq_cmp(_mpq, tmp_frac);
915 return - arg2.compare(*
this);
918 return mpq_cmp(_mpq,
dynamic_cast<_knumfraction
const &
>(arg2)._mpq);
921int _knumfloat::compare(_knumber
const &arg2)
const
923 if (arg2.type() != FloatType) {
925 if (arg2.type() == IntegerType) {
928 dynamic_cast<_knuminteger
const &
>(arg2)._mpz);
929 }
else if (arg2.type() == FractionType) {
932 dynamic_cast<_knumfraction
const &
>(arg2)._mpq);
934 return - arg2.compare(*
this);
936 int cmp_result = mpf_cmp(_mpf, tmp_float);
937 mpf_clear(tmp_float);
941 return mpf_cmp(_mpf,
dynamic_cast<_knumfloat
const &
>(arg2)._mpf);
946_knumerror::operator
signed long int (
void)
const
949 if (_error == Infinity)
951 if (_error == MinusInfinity)
957_knumerror::operator
unsigned long int (
void)
const
960 if (_error == Infinity)
962 if (_error == MinusInfinity)
969_knuminteger::operator
signed long int (
void)
const
971 return mpz_get_si(_mpz);
974_knumfraction::operator
signed long int (
void)
const
976 return static_cast<signed long int>(mpq_get_d(_mpq));
979_knumfloat::operator
signed long int (
void)
const
981 return mpf_get_si(_mpf);
984_knuminteger::operator
unsigned long int (
void)
const
986 return mpz_get_ui(_mpz);
989_knumfraction::operator
unsigned long int (
void)
const
991 return static_cast<unsigned long int>(mpq_get_d(_mpq));
994_knumfloat::operator
unsigned long int (
void)
const
996 return mpf_get_ui(_mpf);
1001_knumerror::operator double (
void)
const
1003 if (_error == Infinity)
1005 if (_error == MinusInfinity)
1011_knuminteger::operator double (
void)
const
1013 return mpz_get_d(_mpz);
1016_knumfraction::operator double (
void)
const
1018 return mpq_get_d(_mpq);
1021_knumfloat::operator double (
void)
const
1023 return mpf_get_d(_mpf);
1029_knuminteger * _knuminteger::intAnd(_knuminteger
const &arg2)
const
1031 _knuminteger * tmp_num =
new _knuminteger();
1033 mpz_and(tmp_num->_mpz, _mpz, arg2._mpz);
1038_knuminteger * _knuminteger::intOr(_knuminteger
const &arg2)
const
1040 _knuminteger * tmp_num =
new _knuminteger();
1042 mpz_ior(tmp_num->_mpz, _mpz, arg2._mpz);
1047_knumber * _knuminteger::mod(_knuminteger
const &arg2)
const
1049 if(mpz_cmp_si(arg2._mpz, 0) == 0)
return new _knumerror(UndefinedNumber);
1051 _knuminteger * tmp_num =
new _knuminteger();
1053 mpz_mod(tmp_num->_mpz, _mpz, arg2._mpz);
1058_knumber * _knuminteger::shift(_knuminteger
const &arg2)
const
1062 mpz_init_set (tmp_mpz, arg2._mpz);
1064 if (! mpz_fits_slong_p(tmp_mpz)) {
1066 return new _knumerror(UndefinedNumber);
1069 signed long int tmp_arg2 = mpz_get_si(tmp_mpz);
1073 _knuminteger * tmp_num =
new _knuminteger();
1076 mpz_mul_2exp(tmp_num->_mpz, _mpz, tmp_arg2);
1078 mpz_tdiv_q_2exp(tmp_num->_mpz, _mpz, -tmp_arg2);