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