00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include <math.h>
00021 #include <config.h>
00022
00023 #ifdef HAVE_STDLIB_H
00024 #include <stdlib.h>
00025 #endif
00026 #include <qregexp.h>
00027 #include <qstring.h>
00028
00029 #include "knumber_priv.h"
00030
00031 _knumerror::_knumerror(_knumber const & num)
00032 {
00033 switch(num.type()) {
00034 case SpecialType:
00035 _error = dynamic_cast<_knumerror const &>(num)._error;
00036 break;
00037 case IntegerType:
00038 case FractionType:
00039 case FloatType:
00040
00041 break;
00042 }
00043 }
00044
00045
00046
00047 _knuminteger::_knuminteger(unsigned long long int num)
00048 {
00049 mpz_init(_mpz);
00050 #if SIZEOF_UNSIGNED_LONG == 8
00051 mpz_init_set_ui(_mpz, static_cast<unsigned long int>(num));
00052 #elif SIZEOF_UNSIGNED_LONG == 4
00053 mpz_set_ui(_mpz, static_cast<unsigned long int>(num >> 32));
00054 mpz_mul_2exp(_mpz, _mpz, 32);
00055 mpz_add_ui(_mpz, _mpz, static_cast<unsigned long int>(num));
00056 #else
00057 #error "SIZEOF_UNSIGNED_LONG is a unhandled case"
00058 #endif
00059 }
00060
00061
00062 _knuminteger::_knuminteger(_knumber const & num)
00063 {
00064 mpz_init(_mpz);
00065
00066 switch(num.type()) {
00067 case IntegerType:
00068 mpz_set(_mpz, dynamic_cast<_knuminteger const &>(num)._mpz);
00069 break;
00070 case FractionType:
00071 case FloatType:
00072 case SpecialType:
00073
00074 break;
00075 }
00076 }
00077
00078 _knumfraction::_knumfraction(_knumber const & num)
00079 {
00080 mpq_init(_mpq);
00081
00082 switch(num.type()) {
00083 case IntegerType:
00084 mpq_set_z(_mpq, dynamic_cast<_knuminteger const &>(num)._mpz);
00085 break;
00086 case FractionType:
00087 mpq_set(_mpq, dynamic_cast<_knumfraction const &>(num)._mpq);
00088 break;
00089 case FloatType:
00090 case SpecialType:
00091
00092 break;
00093 }
00094 }
00095
00096 _knumfloat::_knumfloat(_knumber const & num)
00097 {
00098 mpf_init(_mpf);
00099
00100 switch(num.type()) {
00101 case IntegerType:
00102 mpf_set_z(_mpf, dynamic_cast<_knuminteger const &>(num)._mpz);
00103 break;
00104 case FractionType:
00105 mpf_set_q(_mpf, dynamic_cast<_knumfraction const &>(num)._mpq);
00106 break;
00107 case FloatType:
00108 mpf_set(_mpf, dynamic_cast<_knumfloat const &>(num)._mpf);
00109 break;
00110 case SpecialType:
00111
00112 break;
00113 }
00114 }
00115
00116
00117
00118 _knumerror::_knumerror(QString const & num)
00119 {
00120 if (num == "nan")
00121 _error = UndefinedNumber;
00122 else if (num == "inf")
00123 _error = Infinity;
00124 else if (num == "-inf")
00125 _error = MinusInfinity;
00126 }
00127
00128 _knuminteger::_knuminteger(QString const & num)
00129 {
00130 mpz_init(_mpz);
00131 mpz_set_str(_mpz, num.ascii(), 10);
00132 }
00133
00134 _knumfraction::_knumfraction(QString const & num)
00135 {
00136 mpq_init(_mpq);
00137 if (QRegExp("^[+-]?\\d+(\\.\\d*)?(e[+-]?\\d+)?$").exactMatch(num)) {
00138
00139
00140 unsigned long int digits_after_dot = ((num.section( '.', 1, 1)).section('e', 0, 0)).length();
00141 QString tmp_num = num.section('e', 0, 0).remove('.');
00142 mpq_set_str(_mpq, tmp_num.ascii(), 10);
00143 mpz_t tmp_int;
00144 mpz_init(tmp_int);
00145 mpz_ui_pow_ui (tmp_int, 10, digits_after_dot);
00146 mpz_mul(mpq_denref(_mpq), mpq_denref(_mpq), tmp_int);
00147
00148 if (! (tmp_num = num.section('e', 1, 1)).isEmpty()) {
00149 long int tmp_exp = tmp_num.toLong();
00150 if (tmp_exp > 0) {
00151 mpz_ui_pow_ui (tmp_int, 10,
00152 static_cast<unsigned long int>(tmp_exp));
00153 mpz_mul(mpq_numref(_mpq), mpq_numref(_mpq), tmp_int);
00154 } else {
00155 mpz_ui_pow_ui (tmp_int, 10,
00156 static_cast<unsigned long int>(-tmp_exp));
00157 mpz_mul(mpq_denref(_mpq), mpq_denref(_mpq), tmp_int);
00158 }
00159 }
00160 mpz_clear(tmp_int);
00161 } else
00162 mpq_set_str(_mpq, num.ascii(), 10);
00163 mpq_canonicalize(_mpq);
00164 }
00165
00166 _knumfloat::_knumfloat(QString const & num)
00167 {
00168 mpf_init(_mpf);
00169 mpf_set_str(_mpf, num.ascii(), 10);
00170 }
00171
00172 _knuminteger const & _knuminteger::operator = (_knuminteger const & num)
00173 {
00174 if (this == &num)
00175 return *this;
00176
00177 mpz_set(_mpz, num._mpz);
00178 return *this;
00179 }
00180
00181 QString const _knumerror::ascii(int prec) const
00182 {
00183 static_cast<void>(prec);
00184
00185 switch(_error) {
00186 case UndefinedNumber:
00187 return QString("nan");
00188 case Infinity:
00189 return QString("inf");
00190 case MinusInfinity:
00191 return QString("-inf");
00192 default:
00193 return QString::null;
00194 }
00195 }
00196
00197 QString const _knuminteger::ascii(int prec) const
00198 {
00199 static_cast<void>(prec);
00200 char *tmp_ptr;
00201
00202 gmp_asprintf(&tmp_ptr, "%Zd", _mpz);
00203 QString ret_str = tmp_ptr;
00204
00205 free(tmp_ptr);
00206 return ret_str;
00207 }
00208
00209 QString const _knumfraction::ascii(int prec) const
00210 {
00211 static_cast<void>(prec);
00212 char *tmp_ptr = mpq_get_str(0, 10, _mpq);
00213 QString ret_str = tmp_ptr;
00214
00215 free(tmp_ptr);
00216
00217 return ret_str;
00218 }
00219
00220 QString const _knumfloat::ascii(int prec) const
00221 {
00222 QString ret_str;
00223 char *tmp_ptr;
00224 if (prec > 0)
00225 gmp_asprintf(&tmp_ptr, ("%." + QString().setNum(prec) + "Fg").ascii(), _mpf);
00226 else
00227 gmp_asprintf(&tmp_ptr, "%Fg", _mpf);
00228
00229 ret_str = tmp_ptr;
00230
00231 free(tmp_ptr);
00232
00233 return ret_str;
00234 }
00235
00236
00237 bool _knumfraction::isInteger(void) const
00238 {
00239 if (mpz_cmp_ui(mpq_denref(_mpq), 1) == 0)
00240 return true;
00241 else
00242 return false;
00243 }
00244
00245
00246 _knumber * _knumerror::abs(void) const
00247 {
00248 _knumerror * tmp_num = new _knumerror(*this);
00249
00250 if(_error == MinusInfinity) tmp_num->_error = Infinity;
00251
00252 return tmp_num;
00253 }
00254
00255 _knumber * _knuminteger::abs(void) const
00256 {
00257 _knuminteger * tmp_num = new _knuminteger();
00258
00259 mpz_abs(tmp_num->_mpz, _mpz);
00260
00261 return tmp_num;
00262 }
00263
00264 _knumber * _knumfraction::abs(void) const
00265 {
00266 _knumfraction * tmp_num = new _knumfraction();
00267
00268 mpq_abs(tmp_num->_mpq, _mpq);
00269
00270 return tmp_num;
00271 }
00272
00273 _knumber * _knumfloat::abs(void) const
00274 {
00275 _knumfloat * tmp_num = new _knumfloat();
00276
00277 mpf_abs(tmp_num->_mpf, _mpf);
00278
00279 return tmp_num;
00280 }
00281
00282
00283
00284 _knumber * _knumerror::intPart(void) const
00285 {
00286 return new _knumerror(*this);
00287 }
00288
00289 _knumber * _knuminteger::intPart(void) const
00290 {
00291 _knuminteger *tmp_num = new _knuminteger();
00292 mpz_set(tmp_num->_mpz, _mpz);
00293 return tmp_num;
00294 }
00295
00296 _knumber * _knumfraction::intPart(void) const
00297 {
00298 _knuminteger *tmp_num = new _knuminteger();
00299
00300 mpz_set_q(tmp_num->_mpz, _mpq);
00301
00302 return tmp_num;
00303 }
00304
00305 _knumber * _knumfloat::intPart(void) const
00306 {
00307 _knuminteger *tmp_num = new _knuminteger();
00308
00309 mpz_set_f(tmp_num->_mpz, _mpf);
00310
00311 return tmp_num;
00312 }
00313
00314
00315
00316
00317 int _knumerror::sign(void) const
00318 {
00319 switch(_error) {
00320 case Infinity:
00321 return 1;
00322 case MinusInfinity:
00323 return -1;
00324 default:
00325 return 0;
00326 }
00327 }
00328
00329 int _knuminteger::sign(void) const
00330 {
00331 return mpz_sgn(_mpz);
00332 }
00333
00334 int _knumfraction::sign(void) const
00335 {
00336 return mpq_sgn(_mpq);
00337 }
00338
00339 int _knumfloat::sign(void) const
00340 {
00341 return mpf_sgn(_mpf);
00342 }
00343
00344
00345
00346 #warning _cbrt for now this is a stupid work around
00347 static void _cbrt(mpf_t &num)
00348 {
00349 double tmp_num = cbrt(mpf_get_d(num));
00350 mpf_init_set_d(num, tmp_num);
00351 }
00352
00353
00354 _knumber * _knumerror::cbrt(void) const
00355 {
00356
00357 _knumerror *tmp_num = new _knumerror(*this);
00358
00359 return tmp_num;
00360 }
00361
00362 _knumber * _knuminteger::cbrt(void) const
00363 {
00364 _knuminteger * tmp_num = new _knuminteger();
00365
00366 if(mpz_root(tmp_num->_mpz, _mpz, 3))
00367 return tmp_num;
00368
00369 delete tmp_num;
00370
00371 _knumfloat * tmp_num2 = new _knumfloat();
00372 mpf_set_z(tmp_num2->_mpf, _mpz);
00373
00374 _cbrt(tmp_num2->_mpf);
00375
00376 return tmp_num2;
00377 }
00378
00379 _knumber * _knumfraction::cbrt(void) const
00380 {
00381 _knumfraction * tmp_num = new _knumfraction();
00382 if (mpz_root(mpq_numref(tmp_num->_mpq), mpq_numref(_mpq), 3)
00383 && mpz_root(mpq_denref(tmp_num->_mpq), mpq_denref(_mpq), 3))
00384 return tmp_num;
00385
00386 delete tmp_num;
00387
00388 _knumfloat * tmp_num2 = new _knumfloat();
00389 mpf_set_q(tmp_num2->_mpf, _mpq);
00390
00391 _cbrt(tmp_num2->_mpf);
00392
00393 return tmp_num2;
00394 }
00395
00396 _knumber * _knumfloat::cbrt(void) const
00397 {
00398 _knumfloat * tmp_num = new _knumfloat(*this);
00399
00400 _cbrt(tmp_num->_mpf);
00401
00402 return tmp_num;
00403 }
00404
00405
00406
00407
00408 _knumber * _knumerror::sqrt(void) const
00409 {
00410 _knumerror *tmp_num = new _knumerror(*this);
00411
00412 if(_error == MinusInfinity) tmp_num->_error = UndefinedNumber;
00413
00414 return tmp_num;
00415 }
00416
00417 _knumber * _knuminteger::sqrt(void) const
00418 {
00419 if (mpz_sgn(_mpz) < 0) {
00420 _knumerror *tmp_num = new _knumerror(UndefinedNumber);
00421 return tmp_num;
00422 }
00423 if (mpz_perfect_square_p(_mpz)) {
00424 _knuminteger * tmp_num = new _knuminteger();
00425
00426 mpz_sqrt(tmp_num->_mpz, _mpz);
00427
00428 return tmp_num;
00429 } else {
00430 _knumfloat * tmp_num = new _knumfloat();
00431 mpf_set_z(tmp_num->_mpf, _mpz);
00432 mpf_sqrt(tmp_num->_mpf, tmp_num->_mpf);
00433
00434 return tmp_num;
00435 }
00436 }
00437
00438 _knumber * _knumfraction::sqrt(void) const
00439 {
00440 if (mpq_sgn(_mpq) < 0) {
00441 _knumerror *tmp_num = new _knumerror(UndefinedNumber);
00442 return tmp_num;
00443 }
00444 if (mpz_perfect_square_p(mpq_numref(_mpq))
00445 && mpz_perfect_square_p(mpq_denref(_mpq))) {
00446 _knumfraction * tmp_num = new _knumfraction();
00447 mpq_set(tmp_num->_mpq, _mpq);
00448 mpz_sqrt(mpq_numref(tmp_num->_mpq), mpq_numref(tmp_num->_mpq));
00449 mpz_sqrt(mpq_denref(tmp_num->_mpq), mpq_denref(tmp_num->_mpq));
00450
00451 return tmp_num;
00452 } else {
00453 _knumfloat * tmp_num = new _knumfloat();
00454 mpf_set_q(tmp_num->_mpf, _mpq);
00455 mpf_sqrt(tmp_num->_mpf, tmp_num->_mpf);
00456
00457 return tmp_num;
00458 }
00459
00460 _knumfraction * tmp_num = new _knumfraction();
00461
00462 return tmp_num;
00463 }
00464
00465 _knumber * _knumfloat::sqrt(void) const
00466 {
00467 if (mpf_sgn(_mpf) < 0) {
00468 _knumerror *tmp_num = new _knumerror(UndefinedNumber);
00469 return tmp_num;
00470 }
00471 _knumfloat * tmp_num = new _knumfloat();
00472
00473 mpf_sqrt(tmp_num->_mpf, _mpf);
00474
00475 return tmp_num;
00476 }
00477
00478
00479
00480 _knumber * _knumerror::change_sign(void) const
00481 {
00482 _knumerror * tmp_num = new _knumerror();
00483
00484 if(_error == Infinity) tmp_num->_error = MinusInfinity;
00485 if(_error == MinusInfinity) tmp_num->_error = Infinity;
00486
00487 return tmp_num;
00488 }
00489
00490 _knumber * _knuminteger::change_sign(void) const
00491 {
00492 _knuminteger * tmp_num = new _knuminteger();
00493
00494 mpz_neg(tmp_num->_mpz, _mpz);
00495
00496 return tmp_num;
00497 }
00498
00499 _knumber * _knumfraction::change_sign(void) const
00500 {
00501 _knumfraction * tmp_num = new _knumfraction();
00502
00503 mpq_neg(tmp_num->_mpq, _mpq);
00504
00505 return tmp_num;
00506 }
00507
00508 _knumber *_knumfloat::change_sign(void) const
00509 {
00510 _knumfloat * tmp_num = new _knumfloat();
00511
00512 mpf_neg(tmp_num->_mpf, _mpf);
00513
00514 return tmp_num;
00515 }
00516
00517
00518 _knumber * _knumerror::reciprocal(void) const
00519 {
00520 switch(_error) {
00521 case Infinity:
00522 case MinusInfinity:
00523 return new _knuminteger(0);
00524 case UndefinedNumber:
00525 default:
00526 return new _knumerror(UndefinedNumber);
00527 }
00528 }
00529
00530 _knumber * _knuminteger::reciprocal(void) const
00531 {
00532 if(mpz_cmp_si(_mpz, 0) == 0) return new _knumerror(Infinity);
00533
00534 _knumfraction * tmp_num = new _knumfraction(*this);
00535
00536 mpq_inv(tmp_num->_mpq, tmp_num->_mpq);
00537
00538 return tmp_num;
00539 }
00540
00541 _knumber * _knumfraction::reciprocal() const
00542 {
00543 if(mpq_cmp_si(_mpq, 0, 1) == 0) return new _knumerror(Infinity);
00544
00545 _knumfraction * tmp_num = new _knumfraction();
00546
00547 mpq_inv(tmp_num->_mpq, _mpq);
00548
00549 return tmp_num;
00550 }
00551
00552 _knumber *_knumfloat::reciprocal(void) const
00553 {
00554 if(mpf_cmp_si(_mpf, 0) == 0) return new _knumerror(Infinity);
00555
00556 _knumfloat * tmp_num = new _knumfloat();
00557
00558 mpf_div(tmp_num->_mpf, _knumfloat("1.0")._mpf, _mpf);
00559
00560 return tmp_num;
00561 }
00562
00563
00564
00565 _knumber * _knumerror::add(_knumber const & arg2) const
00566 {
00567 if (arg2.type() != SpecialType)
00568 return new _knumerror(_error);
00569
00570 _knumerror const & tmp_arg2 = dynamic_cast<_knumerror const &>(arg2);
00571
00572 if (_error == UndefinedNumber
00573 || tmp_arg2._error == UndefinedNumber
00574 || (_error == Infinity && tmp_arg2._error == MinusInfinity)
00575 || (_error == MinusInfinity && tmp_arg2._error == Infinity)
00576 )
00577 return new _knumerror(UndefinedNumber);
00578
00579 return new _knumerror(_error);
00580 }
00581
00582 _knumber * _knuminteger::add(_knumber const & arg2) const
00583 {
00584 if (arg2.type() != IntegerType)
00585 return arg2.add(*this);
00586
00587 _knuminteger * tmp_num = new _knuminteger();
00588
00589 mpz_add(tmp_num->_mpz, _mpz,
00590 dynamic_cast<_knuminteger const &>(arg2)._mpz);
00591
00592 return tmp_num;
00593 }
00594
00595 _knumber * _knumfraction::add(_knumber const & arg2) const
00596 {
00597 if (arg2.type() == IntegerType) {
00598
00599 _knumfraction tmp_num(arg2);
00600 return tmp_num.add(*this);
00601 }
00602
00603
00604 if (arg2.type() == FloatType || arg2.type() == SpecialType)
00605 return arg2.add(*this);
00606
00607 _knumfraction * tmp_num = new _knumfraction();
00608
00609 mpq_add(tmp_num->_mpq, _mpq,
00610 dynamic_cast<_knumfraction const &>(arg2)._mpq);
00611
00612 return tmp_num;
00613 }
00614
00615 _knumber *_knumfloat::add(_knumber const & arg2) const
00616 {
00617 if (arg2.type() == SpecialType)
00618 return arg2.add(*this);
00619
00620 if (arg2.type() != FloatType) {
00621
00622 _knumfloat tmp_num(arg2);
00623 return tmp_num.add(*this);
00624 }
00625
00626 _knumfloat * tmp_num = new _knumfloat();
00627
00628 mpf_add(tmp_num->_mpf, _mpf,
00629 dynamic_cast<_knumfloat const &>(arg2)._mpf);
00630
00631 return tmp_num;
00632 }
00633
00634
00635 _knumber * _knumerror::multiply(_knumber const & arg2) const
00636 {
00637
00638 switch(arg2.type()) {
00639 case SpecialType:
00640 {
00641 _knumerror const & tmp_arg2 = dynamic_cast<_knumerror const &>(arg2);
00642 if (_error == UndefinedNumber || tmp_arg2._error == UndefinedNumber)
00643 return new _knumerror(UndefinedNumber);
00644 if ( this->sign() * arg2.sign() > 0)
00645 return new _knumerror(Infinity);
00646 else
00647 return new _knumerror(MinusInfinity);
00648 }
00649 case IntegerType:
00650 case FractionType:
00651 case FloatType:
00652 {
00653 int sign_arg2 = arg2.sign();
00654 if (_error == UndefinedNumber || sign_arg2 == 0)
00655 return new _knumerror(UndefinedNumber);
00656 if ( (_error == Infinity && sign_arg2 > 0) ||
00657 (_error == MinusInfinity && sign_arg2 < 0) )
00658 return new _knumerror(Infinity);
00659
00660 return new _knumerror(MinusInfinity);
00661 }
00662 }
00663
00664 return new _knumerror(_error);
00665 }
00666
00667
00668 _knumber * _knuminteger::multiply(_knumber const & arg2) const
00669 {
00670 if (arg2.type() != IntegerType)
00671 return arg2.multiply(*this);
00672
00673 _knuminteger * tmp_num = new _knuminteger();
00674
00675 mpz_mul(tmp_num->_mpz, _mpz,
00676 dynamic_cast<_knuminteger const &>(arg2)._mpz);
00677
00678 return tmp_num;
00679 }
00680
00681 _knumber * _knumfraction::multiply(_knumber const & arg2) const
00682 {
00683 if (arg2.type() == IntegerType) {
00684
00685 _knumfraction tmp_num(arg2);
00686 return tmp_num.multiply(*this);
00687 }
00688
00689
00690 if (arg2.type() == FloatType || arg2.type() == SpecialType)
00691 return arg2.multiply(*this);
00692
00693 _knumfraction * tmp_num = new _knumfraction();
00694
00695 mpq_mul(tmp_num->_mpq, _mpq,
00696 dynamic_cast<_knumfraction const &>(arg2)._mpq);
00697
00698 return tmp_num;
00699 }
00700
00701 _knumber *_knumfloat::multiply(_knumber const & arg2) const
00702 {
00703 if (arg2.type() == SpecialType)
00704 return arg2.multiply(*this);
00705 if (arg2.type() == IntegerType &&
00706 mpz_cmp_si(dynamic_cast<_knuminteger const &>(arg2)._mpz,0) == 0)
00707
00708 return new _knuminteger(0);
00709
00710 if (arg2.type() != FloatType) {
00711
00712 _knumfloat tmp_num(arg2);
00713 return tmp_num.multiply(*this);
00714 }
00715
00716 _knumfloat * tmp_num = new _knumfloat();
00717
00718 mpf_mul(tmp_num->_mpf, _mpf,
00719 dynamic_cast<_knumfloat const &>(arg2)._mpf);
00720
00721 return tmp_num;
00722 }
00723
00724
00725
00726
00727
00728 _knumber * _knumber::divide(_knumber const & arg2) const
00729 {
00730 _knumber * tmp_num = arg2.reciprocal();
00731 _knumber * rslt_num = this->multiply(*tmp_num);
00732
00733 delete tmp_num;
00734
00735 return rslt_num;
00736 }
00737
00738 _knumber *_knumfloat::divide(_knumber const & arg2) const
00739 {
00740 if(mpf_cmp_si(_mpf, 0) == 0) return new _knumerror(Infinity);
00741
00742
00743 _knumfloat * tmp_num = new _knumfloat(arg2);
00744
00745 mpf_div(tmp_num->_mpf, _mpf, tmp_num->_mpf);
00746
00747 return tmp_num;
00748 }
00749
00750
00751
00752
00753 _knumber * _knumerror::power(_knumber const & exponent) const
00754 {
00755 static_cast<void>(exponent);
00756 return new _knumerror(UndefinedNumber);
00757 }
00758
00759 _knumber * _knuminteger::power(_knumber const & exponent) const
00760 {
00761 if (exponent.type() == IntegerType) {
00762
00763 mpz_t tmp_mpz;
00764 mpz_init_set(tmp_mpz,
00765 dynamic_cast<_knuminteger const &>(exponent)._mpz);
00766
00767 if (! mpz_fits_ulong_p(tmp_mpz)) {
00768
00769 mpz_clear(tmp_mpz);
00770
00771 _knumfloat tmp_num1(*this), tmp_num2(exponent);
00772 return tmp_num1.power(tmp_num2);
00773 }
00774
00775 unsigned long int tmp_int = mpz_get_ui(tmp_mpz);
00776 mpz_clear(tmp_mpz);
00777
00778 _knuminteger * tmp_num = new _knuminteger();
00779 mpz_pow_ui(tmp_num->_mpz, _mpz, tmp_int);
00780 return tmp_num;
00781 }
00782 if (exponent.type() == FractionType) {
00783 if (mpz_sgn(_mpz) < 0)
00784 return new _knumerror(UndefinedNumber);
00785
00786
00787 mpz_t tmp_mpz;
00788 mpz_init_set(tmp_mpz,
00789 mpq_denref(dynamic_cast<_knumfraction const &>(exponent)._mpq));
00790
00791 if (! mpz_fits_ulong_p(tmp_mpz)) {
00792
00793 mpz_clear(tmp_mpz);
00794
00795 _knumfloat tmp_num1(*this), tmp_num2(exponent);
00796 return tmp_num1.power(tmp_num2);
00797 }
00798
00799 unsigned long int tmp_int = mpz_get_ui(tmp_mpz);
00800 mpz_clear(tmp_mpz);
00801
00802
00803 _knuminteger * tmp_num = new _knuminteger();
00804 int flag = mpz_root(tmp_num->_mpz, _mpz, tmp_int);
00805 if (flag == 0) {
00806 delete tmp_num;
00807
00808 _knumfloat tmp_num1(*this), tmp_num2(exponent);
00809 return tmp_num1.power(tmp_num2);
00810 }
00811
00812
00813
00814 mpz_init_set(tmp_mpz,
00815 mpq_numref(dynamic_cast<_knumfraction const &>(exponent)._mpq));
00816
00817 if (! mpz_fits_ulong_p(tmp_mpz)) {
00818
00819 mpz_clear(tmp_mpz);
00820
00821 _knumfloat tmp_num1(*this), tmp_num2(exponent);
00822 return tmp_num1.power(tmp_num2);
00823 }
00824 tmp_int = mpz_get_ui(tmp_mpz);
00825 mpz_clear(tmp_mpz);
00826
00827 mpz_pow_ui(tmp_num->_mpz, tmp_num->_mpz, tmp_int);
00828
00829 return tmp_num;
00830 }
00831 if (exponent.type() == FloatType) {
00832
00833 _knumfloat tmp_num(*this);
00834 return tmp_num.power(exponent);
00835 }
00836
00837 return new _knumerror(Infinity);
00838 }
00839
00840 _knumber * _knumfraction::power(_knumber const & exponent) const
00841 {
00842 _knuminteger tmp_num = _knuminteger();
00843
00844 mpz_set(tmp_num._mpz, mpq_numref(_mpq));
00845 _knumber *numer = tmp_num.power(exponent);
00846
00847 mpz_set(tmp_num._mpz, mpq_denref(_mpq));
00848 _knumber *denom = tmp_num.power(exponent);
00849
00850 _knumber *result = numer->divide(*denom);
00851 delete numer;
00852 delete denom;
00853 return result;
00854 }
00855
00856 _knumber * _knumfloat::power(_knumber const & exponent) const
00857 {
00858 return new _knumfloat(pow(static_cast<double>(*this),
00859 static_cast<double>(exponent)));
00860 }
00861
00862
00863 int _knumerror::compare(_knumber const &arg2) const
00864 {
00865 if (arg2.type() != SpecialType) {
00866 switch(_error) {
00867 case Infinity:
00868 return 1;
00869 case MinusInfinity:
00870 return -1;
00871 default:
00872 return 1;
00873 }
00874 }
00875
00876 switch(_error) {
00877 case Infinity:
00878 if (dynamic_cast<_knumerror const &>(arg2)._error == Infinity)
00879
00880 return 0;
00881 return 1;
00882 case MinusInfinity:
00883 if (dynamic_cast<_knumerror const &>(arg2)._error == MinusInfinity)
00884
00885 return 0;
00886 return -1;
00887 default:
00888 if (dynamic_cast<_knumerror const &>(arg2)._error == UndefinedNumber)
00889
00890 return 0;
00891 return -arg2.compare(*this);
00892 }
00893 }
00894
00895 int _knuminteger::compare(_knumber const &arg2) const
00896 {
00897 if (arg2.type() != IntegerType)
00898 return - arg2.compare(*this);
00899
00900 return mpz_cmp(_mpz, dynamic_cast<_knuminteger const &>(arg2)._mpz);
00901 }
00902
00903 int _knumfraction::compare(_knumber const &arg2) const
00904 {
00905 if (arg2.type() != FractionType) {
00906 if (arg2.type() == IntegerType) {
00907 mpq_t tmp_frac;
00908 mpq_init(tmp_frac);
00909 mpq_set_z(tmp_frac,
00910 dynamic_cast<_knuminteger const &>(arg2)._mpz);
00911 int cmp_result = mpq_cmp(_mpq, tmp_frac);
00912 mpq_clear(tmp_frac);
00913 return cmp_result;
00914 } else
00915 return - arg2.compare(*this);
00916 }
00917
00918 return mpq_cmp(_mpq, dynamic_cast<_knumfraction const &>(arg2)._mpq);
00919 }
00920
00921 int _knumfloat::compare(_knumber const &arg2) const
00922 {
00923 if (arg2.type() != FloatType) {
00924 mpf_t tmp_float;
00925 if (arg2.type() == IntegerType) {
00926 mpf_init(tmp_float);
00927 mpf_set_z(tmp_float,
00928 dynamic_cast<_knuminteger const &>(arg2)._mpz);
00929 } else if (arg2.type() == FractionType) {
00930 mpf_init(tmp_float);
00931 mpf_set_q(tmp_float,
00932 dynamic_cast<_knumfraction const &>(arg2)._mpq);
00933 } else
00934 return - arg2.compare(*this);
00935
00936 int cmp_result = mpf_cmp(_mpf, tmp_float);
00937 mpf_clear(tmp_float);
00938 return cmp_result;
00939 }
00940
00941 return mpf_cmp(_mpf, dynamic_cast<_knumfloat const &>(arg2)._mpf);
00942 }
00943
00944
00945
00946 _knumerror::operator signed long int (void) const
00947 {
00948
00949 if (_error == Infinity)
00950 return 0;
00951 if (_error == MinusInfinity)
00952 return 0;
00953 else
00954 return 0;
00955 }
00956
00957 _knumerror::operator unsigned long int (void) const
00958 {
00959
00960 if (_error == Infinity)
00961 return 0;
00962 if (_error == MinusInfinity)
00963 return 0;
00964 else
00965 return 0;
00966 }
00967
00968
00969 _knuminteger::operator signed long int (void) const
00970 {
00971 return mpz_get_si(_mpz);
00972 }
00973
00974 _knumfraction::operator signed long int (void) const
00975 {
00976 return static_cast<signed long int>(mpq_get_d(_mpq));
00977 }
00978
00979 _knumfloat::operator signed long int (void) const
00980 {
00981 return mpf_get_si(_mpf);
00982 }
00983
00984 _knuminteger::operator unsigned long int (void) const
00985 {
00986 return mpz_get_ui(_mpz);
00987 }
00988
00989 _knumfraction::operator unsigned long int (void) const
00990 {
00991 return static_cast<unsigned long int>(mpq_get_d(_mpq));
00992 }
00993
00994 _knumfloat::operator unsigned long int (void) const
00995 {
00996 return mpf_get_ui(_mpf);
00997 }
00998
00999
01000
01001 _knumerror::operator double (void) const
01002 {
01003 if (_error == Infinity)
01004 return INFINITY;
01005 if (_error == MinusInfinity)
01006 return -INFINITY;
01007 else
01008 return NAN;
01009 }
01010
01011 _knuminteger::operator double (void) const
01012 {
01013 return mpz_get_d(_mpz);
01014 }
01015
01016 _knumfraction::operator double (void) const
01017 {
01018 return mpq_get_d(_mpq);
01019 }
01020
01021 _knumfloat::operator double (void) const
01022 {
01023 return mpf_get_d(_mpf);
01024 }
01025
01026
01027
01028
01029 _knuminteger * _knuminteger::intAnd(_knuminteger const &arg2) const
01030 {
01031 _knuminteger * tmp_num = new _knuminteger();
01032
01033 mpz_and(tmp_num->_mpz, _mpz, arg2._mpz);
01034
01035 return tmp_num;
01036 }
01037
01038 _knuminteger * _knuminteger::intOr(_knuminteger const &arg2) const
01039 {
01040 _knuminteger * tmp_num = new _knuminteger();
01041
01042 mpz_ior(tmp_num->_mpz, _mpz, arg2._mpz);
01043
01044 return tmp_num;
01045 }
01046
01047 _knumber * _knuminteger::mod(_knuminteger const &arg2) const
01048 {
01049 if(mpz_cmp_si(arg2._mpz, 0) == 0) return new _knumerror(UndefinedNumber);
01050
01051 _knuminteger * tmp_num = new _knuminteger();
01052
01053 mpz_mod(tmp_num->_mpz, _mpz, arg2._mpz);
01054
01055 return tmp_num;
01056 }
01057
01058 _knumber * _knuminteger::shift(_knuminteger const &arg2) const
01059 {
01060 mpz_t tmp_mpz;
01061
01062 mpz_init_set (tmp_mpz, arg2._mpz);
01063
01064 if (! mpz_fits_slong_p(tmp_mpz)) {
01065 mpz_clear(tmp_mpz);
01066 return new _knumerror(UndefinedNumber);
01067 }
01068
01069 signed long int tmp_arg2 = mpz_get_si(tmp_mpz);
01070 mpz_clear(tmp_mpz);
01071
01072
01073 _knuminteger * tmp_num = new _knuminteger();
01074
01075 if (tmp_arg2 > 0)
01076 mpz_mul_2exp(tmp_num->_mpz, _mpz, tmp_arg2);
01077 else
01078 mpz_tdiv_q_2exp(tmp_num->_mpz, _mpz, -tmp_arg2);
01079
01080
01081 return tmp_num;
01082 }
01083