source: git/kernel/GMPrat.cc @ 1c94e4

spielwiese
Last change on this file since 1c94e4 was 762407, checked in by Oleksandr Motsak <motsak@…>, 12 years ago
config.h is for sources files only FIX: config.h should only be used by source (not from inside kernel/mod2.h!) NOTE: each source file should better include mod2.h right after config.h, while headers should better not include mod2.h.
  • Property mode set to 100644
File size: 10.6 KB
Line 
1// ----------------------------------------------------------------------------
2//  GMPrat.cc
3//  begin of file
4//  originally written by Gerd Sussner, sussner@mi.uni-erlangen.de
5//  copied by Stephan Endrass, endrass@mathematik.uni-mainz.de
6//  23.7.99
7// ----------------------------------------------------------------------------
8
9#define  GMPRAT_CC
10
11#include "config.h"
12#include <kernel/mod2.h>
13
14#ifdef HAVE_SPECTRUM
15
16#ifdef   GMPRAT_PRINT
17#include <iostream.h>
18#ifndef  GMPRAT_IOSTREAM
19#include <stdio.h>
20#endif
21#endif
22
23#include <stdlib.h>
24#include <math.h>
25#include <ctype.h>
26#include <string.h>
27
28#include <kernel/GMPrat.h>
29
30// ----------------------------------------------------------------------------
31//  Miscellaneous
32// ----------------------------------------------------------------------------
33
34Rational Rational::save;    // dummy variable
35
36// ----------------------------------------------------------------------------
37//  disconnect a rational from its reference
38// ----------------------------------------------------------------------------
39
40void    Rational::disconnect( )
41{
42    if( p->n>1)
43    {
44        p->n--;
45        p = new rep;
46    }
47    else
48    {
49        mpq_clear(p->rat);
50    }
51    mpq_init(p->rat);
52}
53
54// ----------------------------------------------------------------------------
55//  Constructors
56// ----------------------------------------------------------------------------
57
58Rational::Rational( )
59{
60    p = new rep;
61    mpq_init( p->rat );
62}
63
64Rational::Rational( int a )
65{
66    p = new rep;
67    mpq_init( p->rat );
68    mpq_set_si( p->rat,(long)a,1 );
69}
70
71Rational::Rational( const Rational& a )
72{
73    a.p->n++;
74    p=a.p;
75}
76
77// ----------------------------------------------------------------------------
78//  Constructors with two arguments: numerator and denominator
79// ----------------------------------------------------------------------------
80
81Rational::Rational(const Rational& a, const Rational& b)
82{
83    p=new rep;
84    mpq_init(p->rat);
85    mpq_div(p->rat, a.p->rat, b.p->rat);
86}
87
88Rational::Rational(int a, int b)
89{
90    if (b<0) a=-a;
91    p=new rep;
92    mpq_init(p->rat);
93    mpq_set_si(p->rat,(long) a,(unsigned long) abs(b));
94    mpq_canonicalize(p->rat);
95}
96
97// ----------------------------------------------------------------------------
98//  Destructor
99// ----------------------------------------------------------------------------
100
101Rational::~Rational()
102{
103  if (--(p->n)==0)
104  {
105    mpq_clear(p->rat);
106    delete p;
107  }
108}
109
110// ----------------------------------------------------------------------------
111//  Assignment operators
112// ----------------------------------------------------------------------------
113
114Rational& Rational::operator=(int a)
115{
116  disconnect();
117  mpq_set_si(p->rat,(long) a,1);
118  return *this;
119}
120
121Rational& Rational::operator=(const Rational& a)
122{
123  a.p->n++;
124  if (--(p->n)==0)
125  {
126    mpq_clear(p->rat);
127    delete p;
128  }
129  p=a.p;
130  return *this;
131}
132
133// ----------------------------------------------------------------------------
134//  Numerator and denominator
135// ----------------------------------------------------------------------------
136
137Rational Rational::get_num( )
138{
139    Rational erg;
140
141    mpq_set_num( erg.p->rat,mpq_numref( p->rat ) );
142
143    return  erg;
144}
145
146int Rational::get_num_si( )
147{
148    return  mpz_get_si( mpq_numref( p->rat ) );
149}
150
151Rational Rational::get_den( )
152{
153    Rational erg;
154
155    mpq_set_num( erg.p->rat,mpq_denref( p->rat ) );
156
157    return  erg;
158}
159
160int Rational::get_den_si( )
161{
162    return  mpz_get_si( mpq_denref( p->rat ) );
163}
164
165// ----------------------------------------------------------------------------
166//  Casting
167// ----------------------------------------------------------------------------
168
169Rational::operator int()
170{
171  mpz_t h;
172  long ret_val;
173
174  mpz_init(h);
175  mpz_tdiv_q(h,mpq_numref(p->rat),mpq_denref(p->rat));
176  ret_val=mpz_get_si(h);
177  mpz_clear(h);
178
179  return ret_val;
180}
181
182// ----------------------------------------------------------------------------
183//  Unary minus
184// ----------------------------------------------------------------------------
185
186Rational
187Rational::operator-()
188{
189  Rational erg;
190
191  mpq_neg(erg.p->rat,p->rat);
192  return erg;
193}
194
195Rational operator - ( const Rational &r )
196{
197  Rational erg;
198
199  mpq_neg(erg.p->rat,r.p->rat);
200  return erg;
201}
202
203// ----------------------------------------------------------------------------
204//  Inverse
205// ----------------------------------------------------------------------------
206
207Rational
208Rational::operator~()
209{
210  Rational erg;
211
212  mpq_inv(erg.p->rat,p->rat);
213  return erg;
214}
215
216// ----------------------------------------------------------------------------
217//  +=, -= ...
218// ----------------------------------------------------------------------------
219
220Rational&
221Rational::operator+=(const Rational &a)
222{
223  mpq_set(save.p->rat,p->rat);
224  disconnect();
225  mpq_add(p->rat,save.p->rat,a.p->rat);
226  return *this;
227}
228
229Rational&
230Rational::operator-=(const Rational &a)
231{
232  mpq_set(save.p->rat,p->rat);
233  disconnect();
234  mpq_sub(p->rat,save.p->rat,a.p->rat);
235  return *this;
236}
237
238Rational&
239Rational::operator*=(const Rational &a)
240{
241  mpq_set(save.p->rat,p->rat);
242  disconnect();
243  mpq_mul(p->rat,save.p->rat,a.p->rat);
244  return *this;
245}
246
247Rational&
248Rational::operator/=(const Rational &a)
249{
250  mpq_set(save.p->rat,p->rat);
251  disconnect();
252  mpq_div(p->rat,save.p->rat,a.p->rat);
253  return *this;
254}
255
256// ----------------------------------------------------------------------------
257//  Increment and decrement
258// ----------------------------------------------------------------------------
259
260Rational&
261Rational::operator++()
262{
263  mpq_set(save.p->rat,p->rat);
264  *this=1;
265  mpq_add(p->rat,p->rat,save.p->rat);
266  return *this;
267}
268
269Rational
270Rational::operator++(int)
271{
272  Rational erg(*this);
273
274  mpq_set(save.p->rat,p->rat);
275  *this=1;
276  mpq_add(p->rat,p->rat,save.p->rat);
277  return erg;
278}
279
280Rational&
281Rational::operator--()
282{
283  mpq_set(save.p->rat,p->rat);
284  *this=1;
285  mpq_sub(p->rat,save.p->rat,p->rat);
286  return *this;
287}
288
289Rational
290Rational::operator--(int)
291{
292  Rational erg(*this);
293
294  mpq_set(save.p->rat,p->rat);
295  *this=1;
296  mpq_sub(p->rat,save.p->rat,p->rat);
297  return erg;
298}
299
300// ----------------------------------------------------------------------------
301//  Relational operators
302// ----------------------------------------------------------------------------
303
304bool operator<(const Rational& a,const Rational& b)
305{
306  if (mpq_cmp(a.p->rat,b.p->rat)<0) return true;
307  return false;
308}
309
310bool operator<=(const Rational& a,const Rational& b)
311{
312  if (mpq_cmp(a.p->rat,b.p->rat)>0) return false;
313  return true;
314}
315
316bool operator>(const Rational& a,const Rational& b)
317{
318  if (mpq_cmp(a.p->rat,b.p->rat)>0) return true;
319  return false;
320}
321
322bool operator>=(const Rational& a,const Rational& b)
323{
324  if (mpq_cmp(a.p->rat,b.p->rat)<0) return false;
325  return true;
326}
327
328bool operator==(const Rational& a,const Rational& b)
329{
330  if (mpq_equal(a.p->rat,b.p->rat)) return true;
331  return false;
332}
333
334bool operator!=(const Rational& a,const Rational& b)
335{
336  if (mpq_equal(a.p->rat,b.p->rat)) return false;
337  return true;
338}
339
340// ----------------------------------------------------------------------------
341//  Ostream
342// ----------------------------------------------------------------------------
343
344#ifdef GMPRAT_PRINT
345ostream& operator<< (ostream& s,const Rational& a)
346{
347    char *snum,*sdenom;
348
349    snum   = mpz_get_str( NULL,10,mpq_numref(a.p->rat) );
350    sdenom = mpz_get_str( NULL,10,mpq_denref(a.p->rat) );
351
352    if( sdenom[0] == '1' && sdenom[1] == '\0' )
353    {
354        #ifdef GMPRAT_IOSTREAM
355            s << snum;
356        #else
357            fprintf( stdout,snum );
358        #endif
359    }
360    else
361    {
362        #ifdef GMPRAT_IOSTREAM
363            s << snum << "/" << sdenom;
364        #else
365            fprintf( stdout,snum );
366            fprintf( stdout,"/" );
367            fprintf( stdout,sdenom );
368        #endif
369    }
370
371    //free( snum );
372    //free( sdenom );
373
374    return s;
375}
376#endif
377
378unsigned int Rational::length( ) const
379{
380    char *snum = (char*)NULL;
381    char *sden = (char*)NULL;
382
383    snum = mpz_get_str( snum,10,mpq_numref( p->rat ) );
384    sden = mpz_get_str( sden,10,mpq_denref( p->rat ) );
385
386    int length = strlen( snum );
387
388    if( sden[0] != '1' || sden[1] != '\0' ) length += strlen( sden ) + 1;
389
390    free( snum );
391    free( sden );
392
393    return  length;
394}
395
396// ----------------------------------------------------------------------------
397//  Operators
398// ----------------------------------------------------------------------------
399
400Rational
401operator+(const Rational& a,const Rational &b)
402{
403  Rational
404    erg(a);
405
406  return erg+=b;
407}
408
409Rational
410operator-(const Rational& a,const Rational &b)
411{
412  Rational
413    erg(a);
414
415  return erg-=b;
416}
417
418Rational
419operator*(const Rational& a,const Rational &b)
420{
421  Rational
422    erg(a);
423
424  return erg*=b;
425}
426
427Rational pow( const Rational& a,int e )
428{
429    Rational erg(1);
430
431    for( int i=0; i<e; i++ )
432    {
433        erg *= a;
434    }
435    return erg;
436}
437
438Rational operator/(const Rational& a,const Rational &b)
439{
440  Rational
441    erg(a);
442
443  return erg/=b;
444}
445
446int sgn(const Rational& a)
447{
448  return mpq_sgn(a.p->rat);
449}
450
451Rational
452abs(const Rational& a)
453{
454  Rational
455    erg;
456
457  if (mpq_sgn(a.p->rat)<0)
458    mpq_neg(erg.p->rat,a.p->rat);
459  else
460    mpq_set(erg.p->rat,a.p->rat);
461  return erg;
462}
463
464Rational gcd( const Rational &a,const Rational &b )
465{
466    if( a == 0 )
467    {
468        if( b == 0 )
469        {
470            return  (Rational)1;
471        }
472        else
473        {
474            return  abs( b );
475        }
476    }
477    else if( b == 0 )
478    {
479        return  abs( a );
480    }
481
482    Rational erg;
483
484    mpz_gcd( mpq_numref( erg.p->rat ),
485            mpq_numref( a.p->rat ),mpq_numref( b.p->rat ) );
486    mpz_gcd( mpq_denref( erg.p->rat ),
487            mpq_denref( a.p->rat ),mpq_denref( b.p->rat ) );
488
489    //mpq_canonicalize( erg.p->rat );
490
491    return  abs( erg );
492}
493
494Rational gcd( Rational *a,int n )
495{
496    if( n == 1 )
497    {
498        return  a[0];
499    }
500
501    Rational g = gcd( a[0],a[1] );
502
503    for( int i=2; i<n; i++ )
504    {
505        g = gcd( g,a[i] );
506    }
507
508    return  g;
509}
510
511Rational lcm( const Rational &a,const Rational &b )
512{
513    if( a == 0 )
514    {
515        return b;
516    }
517    else if( b == 0 )
518    {
519        return a;
520    }
521
522    return a*b/gcd(a,b);
523}
524
525Rational lcm( Rational *a,int n )
526{
527    if( n == 1 )
528    {
529        return  a[0];
530    }
531
532    Rational g = lcm( a[0],a[1] );
533
534    for( int i=2; i<n; i++ )
535    {
536        g = lcm( g,a[i] );
537    }
538
539    return  g;
540}
541
542double  Rational::complexity( ) const
543{
544    double num = mpz_get_d( mpq_numref( p->rat ) );
545    double den = mpz_get_d( mpq_denref( p->rat ) );
546
547    if( num < 0 ) num = -num;
548    if( den < 0 ) den = -den;
549
550    return  ( num > den ? num : den );
551}
552
553#endif /* HAVE_SPECTRUM */
554// ----------------------------------------------------------------------------
555//  GMPrat.cc
556//  end of file
557// ----------------------------------------------------------------------------
Note: See TracBrowser for help on using the repository browser.