00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "stdafx.h"
00021
00022 #include <iostream>
00023
00024 #include <stdio.h>
00025 #include <math.h>
00026 #include "gul_types.h"
00027 #include "guar_exact.h"
00028
00029 namespace guar {
00030
00031 using gul::uint64;
00032 using gul::uint32;
00033
00034
00035
00036
00037 void IntAdd( const unsigned int na, const unsigned long *a,
00038 const unsigned int nb, const unsigned long *b,
00039 unsigned int *nc, unsigned long *c )
00040 {
00041 uint64 l,z=0;
00042 unsigned int i,len;
00043
00044 if( na < nb )
00045 {
00046 len = nb+1;
00047
00048 for( i = 0; i < na; i++ )
00049 {
00050 l = (uint64)a[i] + (uint64)b[i] + z;
00051 c[i] = (unsigned long)(l & 0xffffffff);
00052 z = (l >> 32) & 0xffffffff;
00053 }
00054 for( i = na; i < nb; i++ )
00055 {
00056 l = (uint64)b[i] + z;
00057 c[i] = (unsigned long)(l & 0xffffffff);
00058 z = (l >> 32) & 0xffffffff;
00059 }
00060 if( (c[i] = (unsigned long)z) == 0 ) len -= 1;
00061 }
00062 else
00063 {
00064 len = na+1;
00065
00066 for( i = 0; i < nb; i++ )
00067 {
00068 l = (uint64)a[i] + (uint64)b[i] + z;
00069 c[i] = (unsigned long)(l & 0xffffffff);
00070 z = (l >> 32) & 0xffffffff;
00071 }
00072 for( i = nb; i < na; i++ )
00073 {
00074 l = (uint64)a[i] + z;
00075 c[i] = (unsigned long)(l & 0xffffffff);
00076 z = (l >> 32) & 0xffffffff;
00077 }
00078 if( (c[i] = (unsigned long)z) == 0 ) len -= 1;
00079 }
00080
00081 *nc = len;
00082 }
00083
00084
00085
00086
00087 int IntSub( const unsigned int na, const unsigned long *a,
00088 const unsigned int nb, const unsigned long *b,
00089 unsigned int *nc, unsigned long *c )
00090 {
00091 uint64 l,z=1;
00092 unsigned int i,len;
00093 int sign;
00094
00095
00096
00097 if( nb > na )
00098 sign = -1;
00099 else if( na > nb )
00100 sign = 0;
00101 else
00102 {
00103 i = na-1;
00104 while( (a[i] == b[i]) && (i > 0) )
00105 i--;
00106 sign = b[i] > a[i] ? -1 : 0;
00107 }
00108
00109 if( sign )
00110 {
00111 for( i = 0; i < na; i++ )
00112 {
00113 l = 0xffffffff + (uint64)b[i] - (uint64)a[i] + z;
00114 c[i] = (unsigned long)(l & 0xffffffff);
00115 z = (l >> 32) & 0xffffffff;
00116 }
00117 for( i = na; i < nb; i++ )
00118 {
00119 l = 0xffffffff + (uint64)b[i] + z;
00120 c[i] = (unsigned long)(l & 0xffffffff);
00121 z = (l >> 32) & 0xffffffff;
00122 }
00123 len = nb;
00124 }
00125 else
00126 {
00127 for( i = 0; i < nb; i++ )
00128 {
00129 l = 0xffffffff + (uint64)a[i] - (uint64)b[i] + z;
00130 c[i] = (unsigned long)(l & 0xffffffff);
00131 z = (l >> 32) & 0xffffffff;
00132 }
00133 for( i = nb; i < na; i++ )
00134 {
00135 l = 0xffffffff + (uint64)a[i] + z;
00136 c[i] = (unsigned long)(l & 0xffffffff);
00137 z = (l >> 32) & 0xffffffff;
00138 }
00139 len = na;
00140 }
00141
00142
00143
00144 for( ; (len > 0) && (c[len-1] == 0); len-- );
00145
00146 *nc = len;
00147 return( sign );
00148 }
00149
00150
00151
00152
00153 unsigned long IntMultShort(
00154 const unsigned int na, const unsigned long *a, const unsigned long b,
00155 unsigned long *c )
00156 {
00157 uint64 z, l, m;
00158 unsigned int i;
00159
00160 z = 0;
00161 m = (uint64)b;
00162
00163 for( i = 0; i < na; i++ )
00164 {
00165 l = (uint64)a[i]*m + z;
00166 c[i] = (unsigned long)(l & 0xffffffff);
00167 z = (l >> 32) & 0xffffffff;
00168 }
00169 return((unsigned long)z);
00170 }
00171
00172
00173
00174
00175
00176 void IntMult( const unsigned int na, const unsigned long *a,
00177 const unsigned int nb, const unsigned long *b,
00178 unsigned int *nc, unsigned long *c )
00179 {
00180 uint64 l,z;
00181 unsigned int i,j;
00182
00183 if( (na == 0) || (nb == 0) )
00184 { *nc = 0; return; }
00185
00186 for( i = 0; i < na; i++ )
00187 c[i] = 0;
00188
00189 for( j = 0; j < nb; j++ )
00190 {
00191 z = 0;
00192 for( i = 0; i < na; i++ )
00193 {
00194 l = (uint64)a[i]*(uint64)b[j] +
00195 (uint64)c[i+j] + z;
00196 c[i+j] = (unsigned long)(l & 0xffffffff);
00197 z = (l >> 32) & 0xffffffff;
00198 }
00199 c[i+j] = (unsigned long)z;
00200 }
00201
00202 if( c[na+nb-1] == 0 ) *nc = na+nb-1;
00203 else *nc = na+nb;
00204 }
00205
00206
00207
00208
00209 unsigned long IntDivShort(
00210 const unsigned int na, const unsigned long *a, const unsigned long b,
00211 unsigned int *nq, unsigned long *q )
00212 {
00213 uint64 l, z, d = b;
00214 int i;
00215
00216 z = 0;
00217 for( i = na-1; i >= 0; i-- )
00218 {
00219 l = (z<<32) + ((uint64)a[i]);
00220 q[i] = (unsigned long)(l / d);
00221 z = l % d;
00222 }
00223
00224 if( q[na-1] == 0 )
00225 *nq = na-1;
00226 else
00227 *nq = na;
00228
00229 return((unsigned long)z);
00230 }
00231
00232
00233
00234
00235 int IntDiv( const unsigned int na, const unsigned long *a,
00236 const unsigned int nb, const unsigned long *b,
00237 unsigned int *nq, unsigned long *q,
00238 unsigned int *nr, unsigned long *r )
00239 {
00240 unsigned long *ad, *bd;
00241 uint64 d, z, l, b1, b2, m, ml, qh;
00242 unsigned int i,j;
00243 int sign;
00244
00245 if( na == 0 )
00246 {
00247 *nq = 0;
00248 *nr = 0;
00249 return(-1);
00250 }
00251
00252 if( nb < 2 )
00253 {
00254 if( nb == 0 ) return(0);
00255
00256 r[0] = IntDivShort( na, a, b[0], nq, q );
00257 if( r[0] != 0 ) *nr = 1; else *nr = 0;
00258 return(-1);
00259 }
00260
00261 if( na < nb )
00262 {
00263 memcpy( r, a, na*sizeof(unsigned long) );
00264 *nr = na;
00265 *nq = 0;
00266 return(-1);
00267 }
00268
00269 ad = (unsigned long *)alloca( sizeof(unsigned long)*(na+1) );
00270 if( ad == NULL ) return(0);
00271 bd = (unsigned long *)alloca( sizeof(unsigned long)*nb );
00272 if( bd == NULL ) return(0);
00273
00274 d = LL(0x100000000)/(((uint64)b[nb-1]) + LL(1));
00275
00276 ad[na] = IntMultShort( na, a, (unsigned long)d, ad );
00277 IntMultShort( nb, b, (unsigned long)d, bd );
00278
00279 b1 = bd[nb-1];
00280 b2 = bd[nb-2];
00281
00282 for( i = na; i >= nb; i-- )
00283 {
00284 l = (((uint64)ad[i])<<32) + (uint64)ad[i-1];
00285
00286 if( ad[i] == bd[nb-1] )
00287 qh = 0xffffffff;
00288 else
00289 qh = l/b1;
00290
00291 while( b2*qh > ((l - b1*qh)<<32) + (uint64)ad[i-2] ) qh--;
00292
00293 z = 1;
00294 sign = 0;
00295 m = 0;
00296 for( j = 0; j < nb; j++ )
00297 {
00298 m = qh*(uint64)bd[j] + m;
00299 ml = m & 0xffffffff;
00300 m = m >> 32;
00301
00302 l = 0xffffffff + (uint64)ad[i-nb+j] - ml + z;
00303 ad[i-nb+j] = (unsigned long)(l & 0xffffffff);
00304 z = (l >> 32) & 0xffffffff;
00305 }
00306 l = 0xffffffff + (uint64)ad[i] - m + z;
00307 ad[i] = (unsigned long)(l & 0xffffffff);
00308 z = (l >> 32) & 0xffffffff;
00309 sign = (z - LL(1) != 0 ? -1 : 0);
00310
00311 if( sign )
00312 {
00313 qh--;
00314
00315 z = 0;
00316 for( j = 0; j < nb; j++ )
00317 {
00318 l = (uint64)ad[i-nb+j] + (uint64)bd[j] + z;
00319 ad[i-nb+j] = (unsigned long)(l & 0xffffffff);
00320 z = (l >> 32) & 0xffffffff;
00321 }
00322 l = (uint64)ad[i] + z;
00323 ad[i] = (unsigned long)(l & 0xffffffff);
00324 }
00325
00326 q[i-nb] = (unsigned long)qh;
00327 }
00328
00329 for( i = nb-1; (i > 0) && (ad[i]==0); i-- );
00330
00331 if( (i > 0) || (ad[0] != 0) )
00332
00333 IntDivShort( i+1, ad, (unsigned long)d, nr, r );
00334 else
00335 *nr = 0;
00336
00337 if( q[na-nb] == 0 )
00338 *nq = na-nb;
00339 else
00340 *nq = na-nb+1;
00341
00342 return(-1);
00343 }
00344
00345
00346
00347
00348
00349 int DoubleToInt( const double d, const unsigned int na, unsigned long *a,
00350 int *retLen )
00351 {
00352 double f,m;
00353 int i,sign,len;
00354
00355 if( d < 0.0 )
00356 {
00357 sign = -1;
00358 m = fabs( d );
00359 }
00360 else
00361 {
00362 sign = 0;
00363 m = d;
00364 }
00365
00366 len = 0;
00367 while( m >= 1.0 )
00368 {
00369 m = m / (double)(LL(0x100000000));
00370 len++;
00371 }
00372 for( i = len-1; i >= 0; i-- )
00373 {
00374 m = m*(double)(LL(0x100000000));
00375 f = floor(m);
00376 a[i] = (unsigned long)f;
00377 m -= f;
00378 }
00379
00380 *retLen = len;
00381 return(sign);
00382 }
00383
00384
00385
00386
00387 Interval operator*( const Interval &a, const Interval &b )
00388 {
00389 Interval c;
00390 double f1,f2;
00391
00392 if( a.m_low >= 0.0 )
00393 {
00394 if( b.m_low >= 0.0 )
00395 {
00396 c.m_low = a.m_low * b.m_low;
00397 c.m_high = a.m_high * b.m_high;
00398 }
00399 else
00400 {
00401 if( b.m_high >= 0 )
00402 {
00403 c.m_low = a.m_high * b.m_low;
00404 c.m_high = a.m_high * b.m_high;
00405 }
00406 else
00407 {
00408 c.m_low = a.m_high * b.m_low;
00409 c.m_high = a.m_low * b.m_high;
00410 }
00411 }
00412 }
00413 else
00414 {
00415 if( a.m_high < 0.0 )
00416 {
00417 if( b.m_low >= 0 )
00418 {
00419 c.m_low = a.m_low * b.m_high;
00420 c.m_high = a.m_high * b.m_low;
00421 }
00422 else
00423 {
00424 if( b.m_high < 0 )
00425 {
00426 c.m_low = a.m_high * b.m_high;
00427 c.m_high = a.m_low * b.m_low;
00428 }
00429 else
00430 {
00431 c.m_low = a.m_low * b.m_high;
00432 c.m_high = a.m_high * b.m_low;
00433 }
00434 }
00435 }
00436 else
00437 {
00438 if( b.m_low >= 0 )
00439 {
00440 c.m_low = a.m_low * b.m_high;
00441 c.m_high = a.m_high * b.m_high;
00442 }
00443 else
00444 {
00445 if( b.m_high < 0 )
00446 {
00447 c.m_low = a.m_high * b.m_low;
00448 c.m_high = a.m_low * b.m_high;
00449 }
00450 else
00451 {
00452 f1 = a.m_low * b.m_high;
00453 f2 = a.m_high * b.m_low;
00454 c.m_low = f1 < f2 ? f1 : f2;
00455
00456 f1 = a.m_low * b.m_low;
00457 f2 = a.m_high * b.m_high;
00458 c.m_high = f1 > f2 ? f1 : f2;
00459 }
00460 }
00461 }
00462 }
00463
00464 c.m_low = c.m_low - DBL_EPSILON*fabs(c.m_low);
00465 c.m_high = c.m_high + DBL_EPSILON*fabs(c.m_high);
00466
00467 return( c );
00468 }
00469
00470 GULAPI rational::rational( void )
00471 {
00472 size_t bsize;
00473 void *buf = gust::PoolAlloc( sizeof(rational_rep), &bsize );
00474 if( buf == NULL ) throw gul::PoolAllocError();
00475 m = new(buf) rational_rep;
00476 }
00477
00478 GULAPI rational::rational( int na, unsigned long *a, int sign )
00479 {
00480 size_t bsize;
00481 void *buf = gust::PoolAlloc( sizeof(rational_rep), &bsize );
00482 if( buf == NULL ) throw gul::PoolAllocError();
00483 m = new(buf) rational_rep(sign,na,a);
00484 }
00485
00486 GULAPI rational::rational( ULong a, int sign )
00487 {
00488 size_t bsize;
00489 void *buf = gust::PoolAlloc( sizeof(rational_rep), &bsize );
00490 if( buf == NULL ) throw gul::PoolAllocError();
00491 m = new(buf) rational_rep(sign,a);
00492 }
00493
00494 GULAPI rational::rational( int sign, int size_a, int size_b )
00495 {
00496 size_t bsize;
00497 void *buf = gust::PoolAlloc( sizeof(rational_rep), &bsize );
00498 if( buf == NULL ) throw gul::PoolAllocError();
00499 m = new(buf) rational_rep( sign, size_a, size_b );
00500 }
00501
00502 GULAPI rational& rational::operator=( const rational& other )
00503 {
00504 other.m->m_refcount++;
00505
00506 if( --m->m_refcount == 0 )
00507 {
00508 m->~rational_rep();
00509 gust::PoolFree( m, sizeof(rational_rep) );
00510 }
00511
00512 m = other.m;
00513
00514 return( *this );
00515 }
00516
00517 GULAPI rational::~rational(void)
00518 {
00519 if( --m->m_refcount == 0 )
00520 {
00521 m->~rational_rep();
00522 gust::PoolFree( m, sizeof(rational_rep) );
00523 }
00524 }
00525
00526 GULAPI rational rational::get_copy() const
00527 {
00528 rational C(m->m_sign,m->m_na,m->m_nb);
00529 unsigned int i;
00530
00531 if( m->m_na )
00532 for( i = 0; i < m->m_na; i++ )
00533 C.m->m_a[i] = m->m_a[i];
00534 if( m->m_nb )
00535 for( i = 0; i < m->m_nb; i++ )
00536 C.m->m_b[i] = m->m_b[i];
00537 return C;
00538 }
00539
00540 GULAPI void rational::calc_bounds( void ) const
00541 {
00542 m->calc_bounds();
00543 }
00544
00545 GULAPI const Interval& rational::get_bounds( void ) const
00546 {
00547 if( !m->m_bounds ) m->calc_bounds();
00548 return(m->m_i);
00549 }
00550
00551 template< class T >
00552 GULAPI void rational::dump( T& num, T& den ) const
00553 {
00554 m->dump( num, den );
00555 }
00556
00557
00558
00559
00560
00561
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576
00577
00578
00579
00580 GULAPI rational operator*( const rational& a, const rational& b )
00581 {
00582 if( (a.m->m_na == 0) || (b.m->m_na == 0) )
00583 {
00584 rational c;
00585 return(c);
00586 }
00587 else
00588 {
00589 rational c( a.m->m_sign ^ b.m->m_sign,
00590 a.m->m_na + b.m->m_na, a.m->m_nb + b.m->m_nb );
00591
00592 IntMult( a.m->m_na, a.m->m_a, b.m->m_na, b.m->m_a,
00593 &c.m->m_na, c.m->m_a );
00594
00595 if( (a.m->m_nb != 0) && (b.m->m_nb != 0) )
00596 {
00597 IntMult( a.m->m_nb, a.m->m_b, b.m->m_nb, b.m->m_b,
00598 &c.m->m_nb, c.m->m_b );
00599 }
00600 else
00601 {
00602 if( b.m->m_nb != 0 )
00603 {
00604 memcpy( c.m->m_b, b.m->m_b, b.m->m_nb*sizeof(unsigned long) );
00605 c.m->m_nb = b.m->m_nb;
00606 }
00607 else if( a.m->m_nb != 0 )
00608 {
00609 memcpy( c.m->m_b, a.m->m_b, a.m->m_nb*sizeof(unsigned long) );
00610 c.m->m_nb = a.m->m_nb;
00611 }
00612 }
00613
00614 return(c);
00615 }
00616 }
00617
00618 GULAPI rational operator+( const rational& A, const rational& B )
00619 {
00620 unsigned long *a1b2,*a2b1,*a1b2_a2b1,*b1b2;
00621 unsigned int na1b2,na2b1,n_a1b2_a2b1,nb1b2;
00622 size_t size_a1b2,size_a2b1,size_a1b2_a2b1,size_b1b2;
00623 int sign,sign2;
00624
00625 if( A.m->m_na == 0 ) return(B);
00626 if( B.m->m_na == 0 ) return(A);
00627
00628 rational c;
00629
00630 if( B.m->m_nb == 0 )
00631 {
00632 a1b2 = A.m->m_a;
00633 na1b2 = A.m->m_na;
00634 size_a1b2 = 0;
00635 }
00636 else
00637 {
00638 a1b2 = (unsigned long *)gust::PoolAlloc(
00639 (A.m->m_na+B.m->m_nb)*sizeof(unsigned long), &size_a1b2 );
00640 if( a1b2 == NULL ) throw gul::PoolAllocError();
00641 IntMult( A.m->m_na, A.m->m_a, B.m->m_nb, B.m->m_b,
00642 &na1b2, a1b2 );
00643 }
00644
00645 if( A.m->m_nb == 0 )
00646 {
00647 a2b1 = B.m->m_a;
00648 na2b1 = B.m->m_na;
00649 size_a2b1 = 0;
00650 }
00651 else
00652 {
00653 a2b1 = (unsigned long *)gust::PoolAlloc(
00654 (B.m->m_na+A.m->m_nb)*sizeof(unsigned long), &size_a2b1 );
00655 if( a2b1 == NULL ) throw gul::PoolAllocError();
00656 IntMult( B.m->m_na, B.m->m_a, A.m->m_nb, A.m->m_b,
00657 &na2b1, a2b1 );
00658 }
00659
00660 n_a1b2_a2b1 = na1b2 > na2b1 ? na1b2 : na2b1;
00661 if( n_a1b2_a2b1 == 0 )
00662 {
00663 if( size_a1b2 ) gust::PoolFree( a1b2, size_a1b2 );
00664 if( size_a2b1 ) gust::PoolFree( a2b1, size_a2b1 );
00665 return(c);
00666 }
00667
00668 sign = A.m->m_sign ^ B.m->m_sign;
00669 if( !sign ) n_a1b2_a2b1++;
00670
00671 a1b2_a2b1 = (unsigned long *)gust::PoolAlloc(
00672 n_a1b2_a2b1*sizeof(unsigned long), &size_a1b2_a2b1 );
00673 if( a1b2_a2b1 == NULL ) throw gul::PoolAllocError();
00674
00675 if( sign )
00676 {
00677 sign2 = IntSub( na1b2, a1b2, na2b1, a2b1, &n_a1b2_a2b1, a1b2_a2b1 );
00678 if( n_a1b2_a2b1 == 0 )
00679 {
00680 gust::PoolFree( a1b2_a2b1, size_a1b2_a2b1 );
00681 a1b2_a2b1 = NULL;
00682 }
00683 }
00684 else
00685 {
00686 sign2 = 0;
00687 IntAdd( na1b2, a1b2, na2b1, a2b1, &n_a1b2_a2b1, a1b2_a2b1 );
00688 }
00689
00690 if( size_a1b2 ) gust::PoolFree( a1b2, size_a1b2 );
00691 if( size_a2b1 ) gust::PoolFree( a2b1, size_a2b1 );
00692
00693 if( n_a1b2_a2b1 == 0 )
00694 {
00695 sign = 0;
00696 b1b2 = NULL;
00697 nb1b2 = 0;
00698 size_b1b2 = 0;
00699 }
00700 else
00701 {
00702 if( A.m->m_sign )
00703 sign = sign2 ^ -1;
00704 else
00705 sign = sign2;
00706
00707 if( A.m->m_nb == 0 )
00708 {
00709 if( B.m->m_nb == 0 )
00710 {
00711 b1b2 = NULL;
00712 nb1b2 = 0;
00713 size_b1b2 = 0;
00714 }
00715 else
00716 {
00717 nb1b2 = B.m->m_nb;
00718 b1b2 = (unsigned long *)gust::PoolAlloc(
00719 nb1b2*sizeof(unsigned long), &size_b1b2 );
00720 if( b1b2 == NULL ) throw gul::PoolAllocError();
00721 memcpy( b1b2, B.m->m_b, nb1b2*sizeof(unsigned long) );
00722 }
00723 }
00724 else if( B.m->m_nb == 0 )
00725 {
00726 nb1b2 = A.m->m_nb;
00727 b1b2 = (unsigned long *)gust::PoolAlloc(
00728 nb1b2*sizeof(unsigned long), &size_b1b2 );
00729 if( b1b2 == NULL ) throw gul::PoolAllocError();
00730 memcpy( b1b2, A.m->m_b, nb1b2*sizeof(unsigned long) );
00731 }
00732 else
00733 {
00734 b1b2 = (unsigned long *)gust::PoolAlloc(
00735 (A.m->m_nb+B.m->m_nb)*sizeof(unsigned long), &size_b1b2 );
00736 if( b1b2 == NULL ) throw gul::PoolAllocError();
00737
00738 IntMult( A.m->m_nb, A.m->m_b, B.m->m_nb, B.m->m_b,
00739 &nb1b2, b1b2 );
00740 }
00741 }
00742
00743 c.m->m_sign = sign;
00744 c.m->m_na = n_a1b2_a2b1;
00745 c.m->m_size_a = size_a1b2_a2b1;
00746 c.m->m_a = a1b2_a2b1;
00747 c.m->m_nb = nb1b2;
00748 c.m->m_size_b = size_b1b2;
00749 c.m->m_b = b1b2;
00750 return(c);
00751 }
00752
00753 GULAPI rational operator/( const rational& A, const rational& B )
00754 {
00755 rational c;
00756
00757 if( A.m == B.m )
00758 return rational(ULong(1));
00759
00760 B.m->reciprocal();
00761 c = A * B;
00762 B.m->reciprocal();
00763
00764 return(c);
00765 }
00766
00767 GULAPI rational operator-( const rational& A, const rational& B )
00768 {
00769 rational c;
00770
00771 if( A.m == B.m )
00772 return c;
00773
00774 if( A.m->m_na == 0 )
00775 {
00776 if( B.m->m_na != 0 )
00777 {
00778 c = B.get_copy();
00779 c.m->m_sign = B.m->m_sign ^ -1;
00780 }
00781 return c;
00782 }
00783
00784 B.m->negative();
00785 c = A + B;
00786 B.m->negative();
00787
00788 return(c);
00789 }
00790
00791
00792
00793
00794 GULAPI void rational::div_mod( rational *q, rational *r ) const
00795 {
00796 if( (m->m_na == 0) || (m->m_nb == 0) )
00797 {
00798 *q = *this;
00799 *r = rational();
00800 return;
00801 }
00802 else if( m->m_na < m->m_nb )
00803 {
00804 *q = rational();
00805 *r = rational( 0, m->m_na, 0 );
00806 memcpy( r->m->m_a, m->m_a, m->m_na*sizeof(unsigned long) );
00807 }
00808 else
00809 {
00810 rational Q( 0, m->m_na - m->m_nb + 1, 0 );
00811 rational R( 0, m->m_nb, 0 );
00812
00813 if( !IntDiv( m->m_na, m->m_a, m->m_nb, m->m_b,
00814 &Q.m->m_na, Q.m->m_a, &R.m->m_na, R.m->m_a ) )
00815 throw gul::Error();
00816
00817 *q = Q; *r = R;
00818 }
00819
00820 if( m->m_sign )
00821 {
00822 *q = *q + rational(ULong(1));
00823 q->m->m_sign = -1;
00824
00825 rational h( 0, m->m_nb, 0 );
00826 memcpy( h.m->m_a, m->m_b, m->m_nb*sizeof(unsigned long) );
00827 *r = h - *r;
00828 }
00829 }
00830
00831
00832
00833
00834
00835
00836
00837
00838
00839
00840
00841
00842
00843
00844
00845
00846
00847
00848
00849
00850
00851
00852
00853
00854
00855
00856
00857
00858
00859
00860
00861
00862
00863
00864
00865 }
00866
00867