00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #include "config.hpp"
00017
00018 #include <sstream>
00019
00020 #include "powerest.hpp"
00021 #include "logarithm.hpp"
00022 #include "big_float.hpp"
00023
00024
00025 #pragma warning(disable : 4244) // here: conversion from long double to size_t,
00026
00027
00028
00029 namespace Arageli
00030 {
00031
00032
00033
00034 void big_float_warning ( const char *s )
00035 {
00036 std::cerr << "Big float warning: " << s << "\n";
00037 }
00038
00039 void big_float_error ( const char *s )
00040 {
00041 std::cerr << "Big float error: " << s << "\n";
00042 }
00043
00044 void big_float_fatal_error(const char *s)
00045 {
00046 std::cerr << "Big float fatal error: \n " << s << "\n";
00047 exit(1);
00048 }
00049
00050
00051 #define CHECK_PREC(p) if ( p < PREC_MIN || p > PREC_MAX ) \
00052 {\
00053 std::cout << p;\
00054 big_float_warning ( "attempt to use illegal precision. PREC_MIN is used as default precision" );\
00055 p = PREC_MIN;\
00056 }\
00057 //else prec = p;
00058 #define CHECK_MODE(m) if ( m < EXACT || m > TO_INF ) \
00059 {\
00060 big_float_warning ( "attempt to set illegal rounding mode. TO_NEAREST is used as default rounding mode" );\
00061 m = TO_NEAREST;\
00062 }\
00063
00064
00065 unsigned fracsion ( int n, unsigned m )
00066 {
00067 if ( n < 0 )
00068 return (m-((-n)%m))%m;
00069 else return (n%m);
00070 }
00071
00072 int get_exponent_of_double(double d)
00073 {
00074
00075 int *pd = (int*)&d;
00076 pd += sizeof ( double ) / sizeof ( int ) - 1;
00077 *pd <<= 1;
00078 *pd += 0x80000000;
00079 *pd >>= ( sizeof ( int ) * 0x8 - 0xB );
00080 return *pd + 1;
00081 }
00082
00083 _Internal::digit * get_mantissa_of_double (double d)
00084 {
00085 _Internal::digit *man;
00086 _Internal::digit *pint;
00087 man = new _Internal::digit [ 4 ];
00088 if (!man)
00089 {
00090 std::cerr << "Big arith fatal error: \n " << "the heap overflow" << "\n";
00091 exit ( 1 );
00092 }
00093 pint = ( _Internal::digit * ) &d;
00094 man [ 0 ] = ((*pint) << 16 ) >> 16;
00095 man [ 1 ] = ( *pint ) >> 16;
00096 pint++;
00097 man [ 2 ] = ((*pint) << 16 ) >> 16;
00098 man [ 3 ] = ((( *pint ) << 12 ) >> 28) + 16;
00099
00100 return man;
00101 }
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120 inline int get_sign ( big_int s )
00121 {
00122 if ( s > 0 ) return 1;
00123 else return -1;
00124 }
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00232 void big_float::normalize_1 ( long prec, long mode )
00233 {
00234 if ( !s.sign() )
00235 {
00236 e = 0;
00237 return;
00238 }
00239
00240 int s_len = s.length() - prec;
00241
00242 if ( mode == EXACT && s.length() <= PREC_MAX || (!s_len) ) return;
00243 if ( s_len < 0 )
00244 {
00245 s = s << -s_len;
00246 e = e + s_len;
00247 return;
00248 }
00249 if ( mode == EXACT )
00250 {
00251 mode = TO_NEAREST;
00252 big_float_error ( "can't perfom operarion with EXACT rounding mode" );
00253 }
00254 int is_digit = 0;
00255 is_digit = ( (s >> s_len - 1) << s_len - 1 != s );
00256 s = s >> s_len - 1;
00257 e = e + s_len - 1;
00258
00259 switch (mode)
00260 {
00261 case TO_NEAREST:
00262 s = ( s + s.sign() ) >> 1;
00263 e = e + 1;
00264 if ( s.length() > prec )
00265 {
00266 s = s >> 1;
00267 e = e + 1;
00268 }
00269 break;
00270
00271 case TO_ZERO :
00272 s = s >> 1;
00273 e = e + 1;
00274 break;
00275 case TO_P_INF :
00276 if ( s.sign() < 0 ) s = s >> 1;
00277 else
00278 {
00279 if ( is_digit ) s = ( s >> 1) + 1;
00280 else
00281 s = s + 1 >> 1;
00282 }
00283 e = e + 1;
00284
00285 if ( s.length() > prec )
00286 {
00287 s = s >> 1;
00288 e = e + 1;
00289 }
00290 break;
00291 case TO_M_INF :
00292 if ( s.sign() > 0 ) s = s >> 1;
00293 else
00294 {
00295 if ( is_digit ) s = ( s >> 1) - 1;
00296 else
00297 s = s - 1 >> 1;
00298 }
00299 e = e + 1;
00300
00301 if ( s.length() > prec )
00302 {
00303 s = s >> 1;
00304 e = e + 1;
00305 }
00306 break;
00307 case TO_INF :
00308
00309 if ( is_digit ) s = ( s >> 1 ) + s.sign();
00310 else
00311 {
00312 if ( s [ 0 ] )
00313 s = ( s >> 1 ) + s.sign();
00314 else s = s >> 1;
00315 }
00316 e = e + 1;
00317
00318 if ( s.length() > prec )
00319 {
00320 s = s >> 1;
00321 e = e + 1;
00322 }
00323 break;
00324
00325 default : break;
00326
00327 }
00328 return;
00329 }
00330
00331 big_int big_float::get_exponent( void ) const
00332 {
00333 return e;
00334 }
00335
00336
00337 big_int big_float::get_significant( void ) const
00338 {
00339 return s;
00340 }
00341
00342
00343 big_float::big_float(void)
00344 {
00345
00346 }
00347
00348 big_float::big_float ( const big_float &b )
00349 {
00350 e = b.e;
00351 s = b.s;
00352 }
00353
00354
00355 big_float::big_float ( const char *str )
00356 {
00357 std::istringstream s ( str );
00358 s >> *this;
00359 }
00360
00361
00362 big_float::big_float ( const big_int &s, const big_int &e )
00363 {
00364 this->e = e;
00365 this->s = s;
00366 normalize_1 ( );
00367
00368 }
00369
00370
00371 big_float::big_float( double b )
00372 {
00373 if ( b == 0.0 )
00374 {
00375 big_float ();
00376 return;
00377 }
00378 _Internal::digit *man = get_mantissa_of_double ( b );
00379
00380 if ( b > 0.0 )
00381 {
00382 s.free_mem_and_alloc_number( 1, man, 4 );
00383 }
00384 else
00385 {
00386 s.free_mem_and_alloc_number( -1, man, 4 );
00387 }
00388 e = get_exponent_of_double ( b ) - 52;
00389 normalize_1 ( );
00390 }
00391 big_float::big_float( int i )
00392 {
00393 *this = big_float( i, 0 );
00394 }
00395
00396
00397 big_float::~big_float(){}
00398
00399
00400
00401
00402 big_float & big_float::operator = ( const big_float &b )
00403 {
00404 if ( this == &b ) return *this;
00405 s = b.s;
00406 e = b.e;
00407 return *this;
00408 }
00409
00410 big_float & big_float::operator = ( const double d )
00411 {
00412 if ( d == 0.0 )
00413 {
00414 s = 0;
00415 e = 0;
00416 return *this;
00417 }
00418 _Internal::digit *man = get_mantissa_of_double ( d );
00419
00420 if ( d > 0.0 )
00421 {
00422 s.free_mem_and_alloc_number( 1, man, 4 );
00423 }
00424 else
00425 {
00426 s.free_mem_and_alloc_number( -1, man, 4 );
00427 }
00428 e = get_exponent_of_double ( d ) - 52;
00429
00430 normalize_1 ( );
00431 return *this;
00432 }
00433
00434 big_float & big_float::operator = ( const int i )
00435 {
00436 return big_float::operator=( double(i) );
00437 }
00438
00439 big_float & big_float::operator = ( const char *str )
00440 {
00441 return *this = big_float::big_float( str );
00442 }
00443
00444
00445
00446
00447 int cmp ( const big_float & a, const big_float & b )
00448 {
00449 big_float temp = a - b;
00450 return temp.get_significant().sign();
00451 }
00452
00453 int operator == ( const big_float & a, const big_float & b )
00454 {
00455 return cmp ( a, b ) == 0;
00456 }
00457
00458 int operator != ( const big_float & a, const big_float & b )
00459 {
00460 return cmp ( a, b ) != 0;
00461 }
00462
00463 int operator > (const big_float & a, const big_float & b)
00464 {
00465 return cmp ( a, b ) == 1;
00466 }
00467
00468 int operator >= (const big_float & a, const big_float & b)
00469 {
00470 return cmp ( a, b ) != -1;
00471 }
00472
00473 int operator < (const big_float & a, const big_float & b)
00474 {
00475 return cmp ( a, b ) == -1;
00476 }
00477
00478 int operator <= (const big_float & a, const big_float & b)
00479 {
00480 return cmp ( a, b ) != 1;
00481 }
00482
00483
00484
00485 void big_float::set_global_precision ( long p )
00486 {
00487 CHECK_PREC(p)
00488 prec = p;
00489 }
00490
00491
00492 void big_float::set_round_mode ( int m )
00493 {
00494 CHECK_MODE(m)
00495 mode = m;
00496 }
00497
00498
00499 big_float operator + ( const big_float &a )
00500 {
00501 return a;
00502 }
00503
00504
00505 big_float operator - ( const big_float &a )
00506 {
00507 big_float b;
00508 b.s = -a.s;
00509 b.e = a.e;
00510 return b;
00511 }
00512
00513
00514 big_float operator + (const big_float & b, const big_float & c)
00515 {
00516 return add ( b, c, big_float::prec, big_float::mode);
00517 }
00518
00519
00520 big_float operator - (const big_float & b, const big_float & c)
00521 {
00522 return sub( b, c, big_float::prec, big_float::mode);
00523 }
00524
00525
00526 big_float operator * (const big_float & b, const big_float & c)
00527 {
00528 return mul( b, c, big_float::prec, big_float::mode);
00529 }
00530
00531
00532 big_float operator / (const big_float & b, const big_float & c)
00533 {
00534 return div ( b, c, big_float::prec, big_float::mode );
00535 }
00536
00537
00538 big_float add(const big_float & b, const big_float & c )
00539 {
00540 return add ( b, c, big_float::prec, big_float::mode );
00541 }
00542
00543
00544 big_float sub (const big_float & b, const big_float & c )
00545 {
00546 return sub( b, c, big_float::prec, big_float::mode );
00547 }
00548
00549
00550 big_float mul( const big_float & b, const big_float & c )
00551 {
00552 return mul( b, c, big_float::prec, big_float::mode );
00553 }
00554
00555
00556 big_float div ( const big_float &b, const big_float & c )
00557 {
00558 return div (b, c, big_float::prec, big_float::mode );
00559 }
00560
00561
00562 big_float add(const big_float & b, const big_float & c, long prec)
00563 {
00564 return add (b, c, prec, big_float::mode );
00565 }
00566
00567
00568 big_float sub(const big_float & b, const big_float & c, long prec)
00569 {
00570 return sub(b,c,prec,big_float::mode);
00571 }
00572
00573
00574 big_float mul(const big_float & b, const big_float & c, long prec)
00575 {
00576 return mul(b,c,prec,big_float::mode);
00577 }
00578
00579
00580 big_float div(const big_float & b, const big_float & c, long prec)
00581 {
00582 return div(b,c,prec,big_float::mode);
00583 }
00584
00585
00586 big_float add ( const big_float & b, const big_float & c, long prec, int mode )
00587 {
00588
00589 CHECK_PREC(prec)
00590 CHECK_MODE(mode)
00591 big_int b_e(b.e), c_e(c.e), b_s(b.s), c_s(c.s);
00592
00593 big_float temp;
00594
00595
00596 if ( !c_s.length() )
00597 {
00598 temp = b;
00599 temp.normalize_1 ( prec, mode );
00600 return temp;
00601 }
00602 if ( !b_s.length() )
00603 {
00604 temp = c;
00605 temp.normalize_1 ( prec, mode );
00606 return temp;
00607 }
00608
00609
00610 long delta = b_s.length() - c_s.length();
00611
00612 if ( delta > 0 )
00613 {
00614 c_s = c_s << delta;
00615 c_e = c_e - delta;
00616 }
00617 else
00618 {
00619 b_s = b_s << -delta;
00620 b_e = b_e + delta;
00621 }
00622
00623 if ( b_e < c_e )
00624 {
00625 swap ( b_e, c_e );
00626 swap ( b_s, c_s );
00627 }
00628
00629 big_int ed = b_e - c_e;
00630
00631 if ( ed > prec && mode != EXACT)
00632
00633 {
00634 temp.s = b_s;
00635 temp.e = b_e;
00636 if ( mode != TO_NEAREST )
00637 {
00638 temp.s = ( temp.s << 1 ) + c_s.sign();
00639 temp.e = temp.e - 1;
00640 }
00641 }
00642 else
00643 {
00644 if ( ed.length() > _Internal::bits_per_digit )
00645 big_float_fatal_error( "can't perfom adding with EXACT rounding mode" );
00646
00647
00648
00649 b_s = b_s << ed;
00650
00651 temp.s = c_s + b_s;
00652 temp.e = c_e;
00653 }
00654 temp.normalize_1 ( prec, mode );
00655 return temp;
00656 }
00657
00658
00659 big_float sub(const big_float & b, const big_float & c, long prec, int mode)
00660 {
00661 big_float temp(c);
00662 temp.s = -temp.s;
00663 temp = add ( b, temp, prec, mode);
00664 return temp;
00665 }
00666
00667
00668 big_float mul( const big_float & b, const big_float & c, long prec, int mode )
00669 {
00670 CHECK_PREC(prec)
00671 CHECK_MODE(mode)
00672 big_float temp;
00673 temp.s = b.get_significant() * c.get_significant();
00674 temp.e = b.get_exponent() + c.get_exponent();
00675 temp.normalize_1 ( prec, mode );
00676 return temp;
00677 }
00678
00679
00680
00681
00682
00683
00684
00685
00686
00687
00688
00689
00690
00691
00692
00693
00694
00695
00696
00697
00698
00699
00700
00701
00702
00703
00704
00705
00706
00707
00708
00709
00710
00711
00712
00713
00714 big_float div ( const big_float & b, const big_float & c, long prec, int mode)
00715 {
00716
00717 if ( c.s==0 ) return big_float();
00718 big_float x;
00719 big_int temp = pow2<big_int> ( prec << 1 );
00720
00721
00722
00723
00724 x.s = temp / c.s;
00725 x.e = -c.e - prec - prec;
00726
00727 x.normalize_1 (prec,mode );
00728
00729 return mul( x, b, prec, mode );
00730 }
00731 big_float divnu ( const big_float & b, const big_float & c, long prec, int mode)
00732 {
00733
00734
00735 short k = 0;
00736 big_float x;
00737 big_float temp = 1;
00738 temp.out ( std::cout, 'd');
00739 x.s = c.s;
00740 while ( x.s.length() % _Internal::bits_per_digit > 0 )
00741 {
00742 x.s = x.s << 1;
00743 k++;
00744 }
00745 x.e = -( int )x.s.length();
00746 for ( int i=0; i < prec + 1; i++ )
00747 {
00748 temp = mul (2,temp,prec,mode) - mul ( mul ( temp,temp,prec,mode ),x,prec,mode );
00749 }
00750 for (int i = 0; i < k; i++)
00751 {
00752 temp = temp * 2;
00753 }
00754 temp.e = temp.e + x.e - c.e;
00755 temp = mul ( b, temp, prec, mode );
00756 return temp;
00757 }
00758
00759 big_float div_i ( const big_int & c )
00760 {
00761 std::size_t l = c.length();
00762
00763 std::size_t step = 1;
00764 big_float res;
00765
00766 res.s = 1;
00767
00768 for ( step = 1 ; step < 32; step <<= 1 )
00769 {
00770 res.s = res.s * ( pow2<big_int> ( l * step + 1 ) - c * res.s );
00771 }
00772
00773 std::cout << 10000 * res.s / pow2<big_int> ( 500)<< std::endl;
00774
00775 return res;
00776 }
00777
00778
00779
00780
00781
00782
00783
00784
00785
00786
00787
00788
00789
00790
00791
00792
00793
00794
00795
00796
00797
00798
00799
00800
00801
00802
00803
00804
00805
00806
00807
00808
00809
00810
00811
00812
00813 void reduce_final_zeros ( std::basic_string<char> &str )
00814 {
00815 std::size_t last_zero = str.length() - 1;
00816
00817 while ( str[ last_zero ] == '0' )
00818 last_zero--;
00819 str.erase(last_zero + 1);
00820 if ( str[last_zero] == '.' )
00821 str.erase(last_zero--);
00822 if ( str[last_zero] == '.' )
00823 str.erase(last_zero);
00824 }
00825
00826 std::istream & operator >> ( std::istream &is , big_float &fnum )
00827 {
00828 char simbol;
00829 big_int dm, de, bm,be;
00830 long add = 0;
00831
00832 std::stringstream bufferm;
00833 std::stringstream buffere;
00834
00835 do
00836 {
00837 is.get( simbol );
00838 } while ( isspace ( simbol ) && !is.fail() );
00839
00840 if ( simbol == '-' || simbol == '+' )
00841 {
00842 bufferm << simbol;
00843 is.get ( simbol );
00844 }
00845
00846 if ( isdigit ( simbol ) )
00847 {
00848 bufferm << simbol;
00849 is.get ( simbol );
00850 while ( isdigit ( simbol ) && !is.fail() )
00851 {
00852 bufferm << simbol;
00853 is.get ( simbol );
00854 }
00855 }
00856
00857 if ( simbol == '.' )
00858 {
00859 simbol = is.get ();
00860 while ( isdigit (simbol) && !is.fail() )
00861 {
00862 bufferm << simbol;
00863 simbol = is.get();
00864 add++;
00865 }
00866 }
00867
00868 if ( simbol == 'e' || simbol == 'E')
00869 {
00870 is.get ( simbol );
00871 if ( simbol == '-' || simbol == '+')
00872 {
00873 buffere << simbol;
00874 is.get ( simbol );
00875 }
00876 while ( isdigit (simbol) && !is.fail() )
00877 {
00878 buffere << simbol;
00879 is.get ( simbol );
00880 }
00881 }
00882
00883 if ( bufferm.str().empty() || bufferm.str() == "+" || bufferm.str() == "-")
00884 {
00885 fnum = big_float ();
00886 }
00887 else
00888 {
00889 bufferm >> dm;
00890 if ( !bufferm.str().empty() && buffere.str() != "+" && buffere.str() != "-" )
00891 buffere >> de;
00892 de = de - add;
00893 do_bin_convert (dm, de, big_float :: prec , bm, be);
00894
00895
00896
00897
00898
00899
00900
00901
00902
00903
00904
00905 fnum = big_float ( bm, be );
00906
00907
00908 }
00909
00910 is.putback ( simbol );
00911 return is;
00912 }
00913
00914 std::ostream & operator << ( std::ostream &os , const big_float &fnum )
00915 {
00916 long flags = os.flags( );
00917
00918 if ( flags & std::ios::scientific )
00919 fnum.out ( os, 'e' );
00920 else if ( flags & std::ios :: fixed )
00921 fnum.out ( os, 'f');
00922 else
00923 fnum.out(os, 'a');
00924 return os;
00925 }
00926
00928 void big_float :: in ( std::istream & ins, char c )
00929 {
00930 switch ( c )
00931 {
00932 case 'f':
00933 ins >> *this;
00934 break;
00935 case 'd':
00936 ins >> s >> e;
00937 normalize_1 ();
00938 break;
00939 default:
00940 big_float_warning ( "unrecognized input format: " );
00941 std::cerr << c << '\n';
00942 ins >> *this;
00943 }
00944 }
00945
00946 void big_float :: out ( std::ostream & os, char c ) const
00947 {
00948 using namespace _Internal;
00949
00950 if ( !s.sign() )
00951 {
00952 os << "0.0";
00953 return;
00954 }
00955
00956 std::stringstream str;
00957 big_int dm, de;
00958 int position;
00959 std::basic_string<char> temp_str;
00960
00961 if ( os.precision() > D_PREC_MAX )
00962 os.precision( D_PREC_MAX );
00963 std::ios_base::fmtflags prev_flags = os.flags ();
00964
00965
00966 if ( s.sign() == -1 )
00967 os << "-";
00968
00969 else if ( prev_flags & std::ios::showpos )
00970 os << "+";
00971
00972 str.setf( std::ios::dec | std::ios::showpos );
00973
00974 switch ( c )
00975 {
00976 case 'f':
00977 position = s.length() + e.to_native_int<int>();
00978
00979
00980 if ( position >= 0 )
00981 position = 1 + ( int )((position + 1) * log (2.0l) / log ( 10.0l ));
00982 else
00983 position = (int)( (long double) position * log (2.0l) / log ( 10.0l ) );
00984
00985 if ( position + os.precision() > 0 )
00986 {
00987
00988 do_dec_convert(dm, de, os.precision() + position, s, e);
00989 str << dm;
00990 temp_str = str.str();
00991 temp_str.erase(0,1);
00992
00993 if ( position > 0 )
00994 {
00995
00996 temp_str.insert( position = temp_str.length() + de.to_native_int<int>(), "." );
00997 }
00998 else
00999 {
01000 os << "0.";
01001 if ( position )
01002 {
01003 os.width( -position );
01004 os.fill ( '0' );
01005 os << "0";
01006 }
01007 if (temp_str.length() <= os.precision() + position )
01008 position--, os << "0";
01009 }
01010
01011
01012 temp_str.erase( position + os.precision() );
01013 reduce_final_zeros ( temp_str );
01014 os << temp_str;
01015 }
01016 else
01017 os << "0.0";
01018
01019 break;
01020
01021 case 'e':
01022
01023 do_dec_convert ( dm, de, os.precision(), s, e );
01024 str << dm;
01025 temp_str = str.str();
01026 temp_str.erase(0,1);
01027 temp_str.insert(1,".");
01028 reduce_final_zeros ( temp_str );
01029
01030
01031 if ( prev_flags & std::ios::uppercase )
01032 os << temp_str << 'E' << de + os.precision();
01033 else
01034 os << temp_str << 'e' << de + os.precision();
01035
01036 break;
01037
01038 case 'a':
01039 do_dec_convert ( dm, de, os.precision(), s, e );
01040 str << dm;
01041 temp_str = str.str();
01042 temp_str.erase(0,1);
01043
01044 if ( de.sign() < 0 && de.to_native_int<int>() > -4 - os.precision () )
01045 {
01046 position = temp_str.length()+ de.to_native_int<int>();
01047 if ( position <= 0 )
01048 {
01049 os << "0.";
01050 if ( position )
01051 {
01052 os.width( -position );
01053 os.fill ( '0' );
01054 os << "0";
01055 }
01056 }
01057 else if ( position != os.precision() )
01058
01059 temp_str.insert ( position, "." );
01060 else
01061 temp_str.insert ( position, ".." );
01062
01063
01064 temp_str.erase( temp_str.length()-1 );
01065 reduce_final_zeros ( temp_str );
01066 os << temp_str;
01067 }
01068 else
01069 {
01070 temp_str.insert( 1,"." );
01071
01072 temp_str.erase( temp_str.length() - 1 );
01073 reduce_final_zeros ( temp_str );
01074
01075
01076 if ( prev_flags & std::ios::uppercase )
01077 os << temp_str << 'E' << de + os.precision();
01078 else
01079 os << temp_str << 'e' << de + os.precision();
01080 }
01081
01082 break;
01083
01084 case 'b':
01085 if ( s.sign() == -1 )
01086 os << '-';
01087 else if ( prev_flags & std::ios::showpos )
01088 os << '+';
01089 for ( int counter = s.length () - 1; counter >= 0 ; counter-- )
01090 os << s [ counter ];
01091
01092 os << '\t';
01093
01094 if ( e.sign() == -1 )
01095 os << '-';
01096 else if ( prev_flags & std::ios::showpos )
01097 os << '+';
01098
01099 for ( int counter = e.length () - 1; counter >= 0 ; counter-- )
01100 os << e [ counter ];
01101 break;
01102
01103 case 'd':
01104 os.setf( std::ios :: dec, std::ios::hex );
01105 os << s << '\t' << e;
01106 break;
01107
01108 case 'h':
01109 os.setf( std::ios::hex, std::ios::dec );
01110 os << s << '\t' << e;
01111 break;
01112
01113 case 'o':
01114 os.setf( std::ios :: oct, std::ios::dec | std::ios::hex );
01115 os << s << '\t' << e;
01116 break;
01117
01118 default:
01119 std::cerr << "Warning!: unrecognized output format:" << c << std::endl;
01120 os.setf( std::ios::dec);
01121 os << s << '\t' << e;
01122 }
01123
01124 os.setf( prev_flags, os.flags() );
01125
01126 }
01127
01128 big_float ceil (const big_float & a)
01129 {
01130 big_float res ( a );
01131 big_int e = a.e;
01132 big_int temp;
01133
01134 if ( e >= 0 )
01135 return res;
01136 if ( e <= -big_int(a.s.length()) )
01137 {
01138 if ( a.s > 0 )
01139 return 1.0;
01140 else return 0.0;
01141 }
01142 temp = ( res.s >> e) << e;
01143 if ( res.s != temp && res.s > 0 )
01144 res.s = temp + pow2<big_int>( e );
01145 else res.s = temp;
01146 return res;
01147 }
01148
01149
01150 big_float floor (const big_float & a)
01151 {
01152 big_float res ( a );
01153 big_int e = a.e;
01154 big_int temp;
01155
01156 if ( e >= 0 )
01157 return res;
01158 if ( e <= -big_int(a.s.length()) )
01159 {
01160 if ( a.s > 0 )
01161 return 1.0;
01162 else return 0.0;
01163 }
01164 temp = ( res.s >> e) << e;
01165 if ( res.s != temp && res.s < 0 )
01166 res.s = temp - pow2<big_int>( e );
01167 else res.s = temp;
01168 return res;
01169
01170 }
01171
01172
01173 big_float frac (const big_float & a)
01174 {
01175 if ( a.e >= 0 )
01176 return 0.0;
01177
01178 big_float res ( a );
01179 if ( res.e <= - big_int(res.s.length()) )
01180 return res;
01181
01182 res.s = res.s - ((res.s >> res.e) << res.e);
01183 return res;
01184 }
01185
01186
01187 big_int iceil (const big_float & a)
01188 {
01189 std::size_t l = a.s.length();
01190 if ( !l ) return l;
01191
01192 big_int temp ( a.s );
01193 if ( a.e > 0 )
01194 {
01195 if ( a.e + a.s.length() > SHRT_MAX )
01196 big_float_fatal_error ( "Can't convert from big_float to big_int ( exponent too large )..." );
01197 return a.s <<a.e;
01198 }
01199 if ( a.e <= -big_int(a.s.length()) )
01200 return ( a.s > 0 ) ? 1 : 0;
01201 temp = temp >> a.e;
01202 if ( temp << a.e != a.s && temp > 0)
01203 return temp + 1;
01204 return temp;
01205 }
01206
01207
01208 big_int ifloor(const big_float & a)
01209 {
01210 std::size_t l = a.s.length();
01211 if ( !l ) return l;
01212
01213 big_int temp ( a.s );
01214 if ( a.e > 0 )
01215 {
01216 if ( a.e + a.s.length() > SHRT_MAX )
01217 big_float_fatal_error ( "Can't convert from big_float to big_int ( exponent too large )..." );
01218 return a.s <<a.e;
01219 }
01220 if ( a.e <= -big_int(a.s.length()) )
01221 return ( a.s > 0 ) ? 0 : -1;
01222 temp = temp >> a.e;
01223 if ( temp << a.e != a.s && temp > 0)
01224 return temp;
01225 return temp - 1;
01226 }
01227
01228 big_float fsqrt( const big_float & b )
01229 {
01230 return fsqrt( b, big_float :: prec, big_float :: mode);
01231 }
01232
01233
01234
01235 big_float fsqrt(const big_float & bf, long prec)
01236 {
01237 return fsqrt( bf, prec, big_float :: mode);
01238 }
01239
01240 big_float fsqrt(const big_float & bf, long prec, int mode)
01241 {
01242 big_float res ( bf );
01243 int l;
01244
01245 if ( res.e [ 0 ] )
01246 {
01247 res.s = res.s << 1;
01248 res.e = res.e - 1;
01249 }
01250
01251 l = (res.s.length() - 2 * prec - 1);
01252 l = (l / 2) * 2;
01253
01254 if ( l > 0 )
01255 {
01256 res.s = res.s >> l;
01257 res.e = res.e + l;
01258 }
01259 else
01260 {
01261 res.s = res.s << (-l) + 2;
01262 res.e = res.e + l - 2;
01263 }
01264 res.s = sqrt ( res.s );
01265 res.e = res.e >> 1;
01266 res.normalize_1 ( prec, mode );
01267
01268 return res;
01269 }
01270
01271 big_float nfsqrt ( const big_float & bf, long prec, int mode )
01272 {
01273 big_float res;
01274
01275 res.e = ((( bf.get_exponent() ) + bf.get_significant().length() - 1) >> 1) + 1;
01276 res.s = 1;
01277
01278 std::cout << "x0 "<<res << std::endl;
01279
01280
01281 std::size_t n = log ( (long double)prec + 1 ) / log ( 2.0l ) + 1;
01282
01283 for ( std::size_t counter = 1; counter <= 2 * n; counter ++ )
01284 {
01285 std::cout << div( bf, res, counter * 2, EXACT ) << std::endl;
01286 res = add ( res, div( bf, res, counter * 2, EXACT ), counter * 2, TO_NEAREST );
01287 std::cout << res << std::endl;
01288 res.e = res.e - 1;
01289 std::cout << counter << " iter \t";
01290 std::cout << res << std::endl;
01291
01292
01293 }
01294 res.normalize_1 ( prec, mode );
01295
01296 return res;
01297 }
01298
01299 big_float frandom ( long prec )
01300 {
01301 CHECK_PREC(prec)
01302 return big_float ( big_int::random_with_length_or_less( prec ), -prec );
01303 }
01304
01305 big_float frandom ( )
01306 {
01307 return big_float ( big_int::random_with_length_or_less( big_float::prec ), -big_float::prec );
01308 }
01309
01310 big_float frandom1 ( long bits, const big_int & exp)
01311 {
01312 CHECK_PREC(bits)
01313 return big_float ( big_int::random_with_length_or_less( bits ) + pow2<big_int>( bits - 1 ) , exp );
01314 }
01315
01316
01317 int big_float::is_NaN( )
01318 {
01319 return 0;
01320 }
01321 int big_float::is_Zero( )
01322 {
01323 return ( s==0 );
01324 }
01325
01326 int big_float::is_pZero( )
01327 {
01328 return ( ( s ==0 ) && (get_sign( s ) == 1) );
01329 }
01330
01331 int big_float::is_mZero()
01332 {
01333 return ((s==0)&&(get_sign(s)==-1));
01334 }
01335
01336 int big_float::is_Special()
01337 {
01338 return ((is_NaN())||(is_Inf())||(is_Zero()));
01339 }
01340
01341
01342 int big_float::is_Inf()
01343 {
01344 return 0;
01345 }
01346
01347 long big_float::prec;
01348 long big_float::mode;
01349
01350
01351 }
01352
01353