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