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);
181 TQString
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");
197 TQString
const _knuminteger::ascii(
int prec)
const 199 static_cast<void>(prec);
202 gmp_asprintf(&tmp_ptr,
"%Zd", _mpz);
203 TQString ret_str = tmp_ptr;
209 TQString
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;
220 TQString
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);
237 bool _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);
317 int _knumerror::sign(
void)
const 329 int _knuminteger::sign(
void)
const 331 return mpz_sgn(_mpz);
334 int _knumfraction::sign(
void)
const 336 return mpq_sgn(_mpq);
339 int _knumfloat::sign(
void)
const 341 return mpf_sgn(_mpf);
346 #warning _cbrt for now this is a stupid work around 347 static 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)));
863 int _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);
895 int _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);
903 int _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);
921 int _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);