source: git/kernel/GMPrat.cc @ 8c5988

spielwiese
Last change on this file since 8c5988 was 35aab3, checked in by Hans Schönemann <hannes@…>, 21 years ago
This commit was generated by cvs2svn to compensate for changes in r6879, which included commits to RCS files with non-trunk default branches. git-svn-id: file:///usr/local/Singular/svn/trunk@6880 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( p->rat );
67    mpq_set_si( p->rat,(long int)a,1 );
68}
69
70Rational::Rational( const Rational& a )
71{
72    a.p->n++;
73    p=a.p;
74}
75
76// ----------------------------------------------------------------------------
77//  Constructors with two arguments: numerator and denominator
78// ----------------------------------------------------------------------------
79
80Rational::Rational(const Rational& a, const Rational& b)
81{
82    p=new rep;
83    mpq_init(p->rat);
84    mpq_div(p->rat, a.p->rat, b.p->rat);
85}
86
87Rational::Rational(int a, int b)
88{
89    if (b<0) a=-a;
90    p=new rep;
91    mpq_init(p->rat);
92    mpq_set_si(p->rat,(long int) a,(unsigned long int) abs(b));
93    mpq_canonicalize(p->rat);
94}
95
96// ----------------------------------------------------------------------------
97//  Destructor
98// ----------------------------------------------------------------------------
99
100Rational::~Rational()
101{
102  if (--p->n==0){
103    mpq_clear(p->rat);
104    delete p;
105  }
106}
107
108// ----------------------------------------------------------------------------
109//  Assignment operators
110// ----------------------------------------------------------------------------
111
112Rational& Rational::operator=(int a)
113{
114  disconnect();
115  mpq_set_si(p->rat,(long int) a,1);
116  return *this;
117}
118
119Rational& Rational::operator=(const Rational& a)
120{
121  a.p->n++;
122  if (--p->n==0){
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
169    h;
170  long int
171    ret_val;
172
173  mpz_init(h);
174  mpz_tdiv_q(h,mpq_numref(p->rat),mpq_denref(p->rat));
175  ret_val=mpz_get_si(h);
176  mpz_clear(h);
177
178  return ret_val;
179}
180
181// ----------------------------------------------------------------------------
182//  Unary minus
183// ----------------------------------------------------------------------------
184
185Rational
186Rational::operator-()
187{
188  Rational
189    erg;
190
191  mpq_neg(erg.p->rat,p->rat);
192  return erg;
193}
194
195Rational operator - ( const Rational &r )
196{
197  Rational
198    erg;
199
200  mpq_neg(erg.p->rat,r.p->rat);
201  return erg;
202}
203
204// ----------------------------------------------------------------------------
205//  Inverse
206// ----------------------------------------------------------------------------
207
208Rational
209Rational::operator~()
210{
211  Rational
212    erg;
213
214  mpq_inv(erg.p->rat,p->rat);
215  return erg;
216}
217
218// ----------------------------------------------------------------------------
219//  +=, -= ...
220// ----------------------------------------------------------------------------
221
222Rational&
223Rational::operator+=(const Rational &a)
224{
225  mpq_set(save.p->rat,p->rat);
226  disconnect();
227  mpq_add(p->rat,save.p->rat,a.p->rat);
228  return *this;
229}
230
231Rational&
232Rational::operator-=(const Rational &a)
233{
234  mpq_set(save.p->rat,p->rat);
235  disconnect();
236  mpq_sub(p->rat,save.p->rat,a.p->rat);
237  return *this;
238}
239
240Rational&
241Rational::operator*=(const Rational &a)
242{
243  mpq_set(save.p->rat,p->rat);
244  disconnect();
245  mpq_mul(p->rat,save.p->rat,a.p->rat);
246  return *this;
247}
248
249Rational&
250Rational::operator/=(const Rational &a)
251{
252  mpq_set(save.p->rat,p->rat);
253  disconnect();
254  mpq_div(p->rat,save.p->rat,a.p->rat);
255  return *this;
256}
257
258// ----------------------------------------------------------------------------
259//  Increment and decrement
260// ----------------------------------------------------------------------------
261
262Rational&
263Rational::operator++()
264{
265  mpq_set(save.p->rat,p->rat);
266  *this=1;
267  mpq_add(p->rat,p->rat,save.p->rat);
268  return *this;
269}
270
271Rational
272Rational::operator++(int)
273{
274  Rational
275    erg(*this);
276
277  mpq_set(save.p->rat,p->rat);
278  *this=1;
279  mpq_add(p->rat,p->rat,save.p->rat);
280  return erg;
281}
282
283Rational&
284Rational::operator--()
285{
286  mpq_set(save.p->rat,p->rat);
287  *this=1;
288  mpq_sub(p->rat,save.p->rat,p->rat);
289  return *this;
290}
291
292Rational
293Rational::operator--(int)
294{
295  Rational
296    erg(*this);
297
298  mpq_set(save.p->rat,p->rat);
299  *this=1;
300  mpq_sub(p->rat,save.p->rat,p->rat);
301  return erg;
302}
303
304// ----------------------------------------------------------------------------
305//  Relational operators
306// ----------------------------------------------------------------------------
307
308bool operator<(const Rational& a,const Rational& b)
309{
310  if (mpq_cmp(a.p->rat,b.p->rat)<0) return true;
311  return false;
312}
313
314bool operator<=(const Rational& a,const Rational& b)
315{
316  if (mpq_cmp(a.p->rat,b.p->rat)>0) return false;
317  return true;
318}
319
320bool operator>(const Rational& a,const Rational& b)
321{
322  if (mpq_cmp(a.p->rat,b.p->rat)>0) return true;
323  return false;
324}
325
326bool operator>=(const Rational& a,const Rational& b)
327{
328  if (mpq_cmp(a.p->rat,b.p->rat)<0) return false;
329  return true;
330}
331
332bool operator==(const Rational& a,const Rational& b)
333{
334  if (mpq_equal(a.p->rat,b.p->rat)) return true;
335  return false;
336}
337
338bool operator!=(const Rational& a,const Rational& b)
339{
340  if (mpq_equal(a.p->rat,b.p->rat)) return false;
341  return true;
342}
343
344// ----------------------------------------------------------------------------
345//  Ostream
346// ----------------------------------------------------------------------------
347
348#ifdef GMPRAT_PRINT
349ostream& operator<< (ostream& s,const Rational& a)
350{
351    char *snum,*sdenom;
352
353    snum   = mpz_get_str( NULL,10,mpq_numref(a.p->rat) );
354    sdenom = mpz_get_str( NULL,10,mpq_denref(a.p->rat) );
355
356    if( sdenom[0] == '1' && sdenom[1] == '\0' )
357    {
358        #ifdef GMPRAT_IOSTREAM
359            s << snum;
360        #else
361            fprintf( stdout,snum );
362        #endif
363    }
364    else
365    {
366        #ifdef GMPRAT_IOSTREAM
367            s << snum << "/" << sdenom;
368        #else
369            fprintf( stdout,snum );
370            fprintf( stdout,"/" );
371            fprintf( stdout,sdenom );
372        #endif
373    }
374
375    //free( snum );
376    //free( sdenom );
377
378    return s;
379}
380#endif
381
382unsigned int Rational::length( ) const
383{
384    char *snum = (char*)NULL;
385    char *sden = (char*)NULL;
386
387    snum = mpz_get_str( snum,10,mpq_numref( p->rat ) );
388    sden = mpz_get_str( sden,10,mpq_denref( p->rat ) );
389
390    int length = strlen( snum );
391
392    if( sden[0] != '1' || sden[1] != '\0' ) length += strlen( sden ) + 1;
393
394    free( snum );
395    free( sden );
396
397    return  length;
398}
399
400// ----------------------------------------------------------------------------
401//  Operators
402// ----------------------------------------------------------------------------
403
404Rational
405operator+(const Rational& a,const Rational &b)
406{
407  Rational
408    erg(a);
409
410  return erg+=b;
411}
412
413Rational
414operator-(const Rational& a,const Rational &b)
415{
416  Rational
417    erg(a);
418
419  return erg-=b;
420}
421
422Rational
423operator*(const Rational& a,const Rational &b)
424{
425  Rational
426    erg(a);
427
428  return erg*=b;
429}
430
431Rational pow( const Rational& a,int e )
432{
433    Rational erg(1);
434
435    for( int i=0; i<e; i++ )
436    {
437        erg *= a;
438    }
439    return erg;
440}
441
442Rational operator/(const Rational& a,const Rational &b)
443{
444  Rational
445    erg(a);
446
447  return erg/=b;
448}
449
450int sgn(const Rational& a)
451{
452  return mpq_sgn(a.p->rat);
453}
454
455Rational
456abs(const Rational& a)
457{
458  Rational
459    erg;
460
461  if (mpq_sgn(a.p->rat)<0)
462    mpq_neg(erg.p->rat,a.p->rat);
463  else
464    mpq_set(erg.p->rat,a.p->rat);
465  return erg;
466}
467
468Rational gcd( const Rational &a,const Rational &b )
469{
470    if( a == 0 )
471    {
472        if( b == 0 )
473        {
474            return  (Rational)1;
475        }
476        else
477        {
478            return  abs( b );
479        }
480    }
481    else if( b == 0 )
482    {
483        return  abs( a );
484    }
485
486    Rational erg;
487
488    mpz_gcd( mpq_numref( erg.p->rat ),
489            mpq_numref( a.p->rat ),mpq_numref( b.p->rat ) );
490    mpz_gcd( mpq_denref( erg.p->rat ),
491            mpq_denref( a.p->rat ),mpq_denref( b.p->rat ) );
492
493    //mpq_canonicalize( erg.p->rat );
494
495    return  abs( erg );
496}
497
498Rational gcd( Rational *a,int n )
499{
500    if( n == 1 )
501    {
502        return  a[0];
503    }
504
505    Rational g = gcd( a[0],a[1] );
506
507    for( int i=2; i<n; i++ )
508    {
509        g = gcd( g,a[i] );
510    }
511
512    return  g;
513}
514
515Rational lcm( const Rational &a,const Rational &b )
516{
517    if( a == 0 )
518    {
519        return b;
520    }
521    else if( b == 0 )
522    {
523        return a;
524    }
525
526    return a*b/gcd(a,b);
527}
528
529Rational lcm( Rational *a,int n )
530{
531    if( n == 1 )
532    {
533        return  a[0];
534    }
535
536    Rational g = lcm( a[0],a[1] );
537
538    for( int i=2; i<n; i++ )
539    {
540        g = lcm( g,a[i] );
541    }
542
543    return  g;
544}
545
546double  Rational::complexity( ) const
547{
548    double num = mpz_get_d( mpq_numref( p->rat ) );
549    double den = mpz_get_d( mpq_denref( p->rat ) );
550
551    if( num < 0 ) num = -num;
552    if( den < 0 ) den = -den;
553
554    return  ( num > den ? num : den );
555}
556
557#endif /* HAVE_SPECTRUM */
558// ----------------------------------------------------------------------------
559//  GMPrat.cc
560//  end of file
561// ----------------------------------------------------------------------------
Note: See TracBrowser for help on using the repository browser.