source: git/kernel/GMPrat.cc @ 7bf4b7

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