source: git/kernel/GMPrat.cc @ 599326

jengelh-datetimespielwiese
Last change on this file since 599326 was 599326, checked in by Kai Krüger <krueger@…>, 13 years ago
Anne, Kai, Frank: - changes to #include "..." statements to allow cleaner build structure - affected directories: omalloc, kernel, Singular - not yet done: IntergerProgramming git-svn-id: file:///usr/local/Singular/svn/trunk@13032 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 <kernel/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 <kernel/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)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) a,(unsigned long) abs(b));
93    mpq_canonicalize(p->rat);
94}
95
96// ----------------------------------------------------------------------------
97//  Destructor
98// ----------------------------------------------------------------------------
99
100Rational::~Rational()
101{
102  if (--(p->n)==0)
103  {
104    mpq_clear(p->rat);
105    delete p;
106  }
107}
108
109// ----------------------------------------------------------------------------
110//  Assignment operators
111// ----------------------------------------------------------------------------
112
113Rational& Rational::operator=(int a)
114{
115  disconnect();
116  mpq_set_si(p->rat,(long) a,1);
117  return *this;
118}
119
120Rational& Rational::operator=(const Rational& a)
121{
122  a.p->n++;
123  if (--(p->n)==0)
124  {
125    mpq_clear(p->rat);
126    delete p;
127  }
128  p=a.p;
129  return *this;
130}
131
132// ----------------------------------------------------------------------------
133//  Numerator and denominator
134// ----------------------------------------------------------------------------
135
136Rational Rational::get_num( )
137{
138    Rational erg;
139
140    mpq_set_num( erg.p->rat,mpq_numref( p->rat ) );
141
142    return  erg;
143}
144
145int Rational::get_num_si( )
146{
147    return  mpz_get_si( mpq_numref( p->rat ) );
148}
149
150Rational Rational::get_den( )
151{
152    Rational erg;
153
154    mpq_set_num( erg.p->rat,mpq_denref( p->rat ) );
155
156    return  erg;
157}
158
159int Rational::get_den_si( )
160{
161    return  mpz_get_si( mpq_denref( p->rat ) );
162}
163
164// ----------------------------------------------------------------------------
165//  Casting
166// ----------------------------------------------------------------------------
167
168Rational::operator int()
169{
170  mpz_t h;
171  long 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 erg;
189
190  mpq_neg(erg.p->rat,p->rat);
191  return erg;
192}
193
194Rational operator - ( const Rational &r )
195{
196  Rational erg;
197
198  mpq_neg(erg.p->rat,r.p->rat);
199  return erg;
200}
201
202// ----------------------------------------------------------------------------
203//  Inverse
204// ----------------------------------------------------------------------------
205
206Rational
207Rational::operator~()
208{
209  Rational erg;
210
211  mpq_inv(erg.p->rat,p->rat);
212  return erg;
213}
214
215// ----------------------------------------------------------------------------
216//  +=, -= ...
217// ----------------------------------------------------------------------------
218
219Rational&
220Rational::operator+=(const Rational &a)
221{
222  mpq_set(save.p->rat,p->rat);
223  disconnect();
224  mpq_add(p->rat,save.p->rat,a.p->rat);
225  return *this;
226}
227
228Rational&
229Rational::operator-=(const Rational &a)
230{
231  mpq_set(save.p->rat,p->rat);
232  disconnect();
233  mpq_sub(p->rat,save.p->rat,a.p->rat);
234  return *this;
235}
236
237Rational&
238Rational::operator*=(const Rational &a)
239{
240  mpq_set(save.p->rat,p->rat);
241  disconnect();
242  mpq_mul(p->rat,save.p->rat,a.p->rat);
243  return *this;
244}
245
246Rational&
247Rational::operator/=(const Rational &a)
248{
249  mpq_set(save.p->rat,p->rat);
250  disconnect();
251  mpq_div(p->rat,save.p->rat,a.p->rat);
252  return *this;
253}
254
255// ----------------------------------------------------------------------------
256//  Increment and decrement
257// ----------------------------------------------------------------------------
258
259Rational&
260Rational::operator++()
261{
262  mpq_set(save.p->rat,p->rat);
263  *this=1;
264  mpq_add(p->rat,p->rat,save.p->rat);
265  return *this;
266}
267
268Rational
269Rational::operator++(int)
270{
271  Rational erg(*this);
272
273  mpq_set(save.p->rat,p->rat);
274  *this=1;
275  mpq_add(p->rat,p->rat,save.p->rat);
276  return erg;
277}
278
279Rational&
280Rational::operator--()
281{
282  mpq_set(save.p->rat,p->rat);
283  *this=1;
284  mpq_sub(p->rat,save.p->rat,p->rat);
285  return *this;
286}
287
288Rational
289Rational::operator--(int)
290{
291  Rational erg(*this);
292
293  mpq_set(save.p->rat,p->rat);
294  *this=1;
295  mpq_sub(p->rat,save.p->rat,p->rat);
296  return erg;
297}
298
299// ----------------------------------------------------------------------------
300//  Relational operators
301// ----------------------------------------------------------------------------
302
303bool operator<(const Rational& a,const Rational& b)
304{
305  if (mpq_cmp(a.p->rat,b.p->rat)<0) return true;
306  return false;
307}
308
309bool operator<=(const Rational& a,const Rational& b)
310{
311  if (mpq_cmp(a.p->rat,b.p->rat)>0) return false;
312  return true;
313}
314
315bool operator>(const Rational& a,const Rational& b)
316{
317  if (mpq_cmp(a.p->rat,b.p->rat)>0) return true;
318  return false;
319}
320
321bool operator>=(const Rational& a,const Rational& b)
322{
323  if (mpq_cmp(a.p->rat,b.p->rat)<0) return false;
324  return true;
325}
326
327bool operator==(const Rational& a,const Rational& b)
328{
329  if (mpq_equal(a.p->rat,b.p->rat)) return true;
330  return false;
331}
332
333bool operator!=(const Rational& a,const Rational& b)
334{
335  if (mpq_equal(a.p->rat,b.p->rat)) return false;
336  return true;
337}
338
339// ----------------------------------------------------------------------------
340//  Ostream
341// ----------------------------------------------------------------------------
342
343#ifdef GMPRAT_PRINT
344ostream& operator<< (ostream& s,const Rational& a)
345{
346    char *snum,*sdenom;
347
348    snum   = mpz_get_str( NULL,10,mpq_numref(a.p->rat) );
349    sdenom = mpz_get_str( NULL,10,mpq_denref(a.p->rat) );
350
351    if( sdenom[0] == '1' && sdenom[1] == '\0' )
352    {
353        #ifdef GMPRAT_IOSTREAM
354            s << snum;
355        #else
356            fprintf( stdout,snum );
357        #endif
358    }
359    else
360    {
361        #ifdef GMPRAT_IOSTREAM
362            s << snum << "/" << sdenom;
363        #else
364            fprintf( stdout,snum );
365            fprintf( stdout,"/" );
366            fprintf( stdout,sdenom );
367        #endif
368    }
369
370    //free( snum );
371    //free( sdenom );
372
373    return s;
374}
375#endif
376
377unsigned int Rational::length( ) const
378{
379    char *snum = (char*)NULL;
380    char *sden = (char*)NULL;
381
382    snum = mpz_get_str( snum,10,mpq_numref( p->rat ) );
383    sden = mpz_get_str( sden,10,mpq_denref( p->rat ) );
384
385    int length = strlen( snum );
386
387    if( sden[0] != '1' || sden[1] != '\0' ) length += strlen( sden ) + 1;
388
389    free( snum );
390    free( sden );
391
392    return  length;
393}
394
395// ----------------------------------------------------------------------------
396//  Operators
397// ----------------------------------------------------------------------------
398
399Rational
400operator+(const Rational& a,const Rational &b)
401{
402  Rational
403    erg(a);
404
405  return erg+=b;
406}
407
408Rational
409operator-(const Rational& a,const Rational &b)
410{
411  Rational
412    erg(a);
413
414  return erg-=b;
415}
416
417Rational
418operator*(const Rational& a,const Rational &b)
419{
420  Rational
421    erg(a);
422
423  return erg*=b;
424}
425
426Rational pow( const Rational& a,int e )
427{
428    Rational erg(1);
429
430    for( int i=0; i<e; i++ )
431    {
432        erg *= a;
433    }
434    return erg;
435}
436
437Rational operator/(const Rational& a,const Rational &b)
438{
439  Rational
440    erg(a);
441
442  return erg/=b;
443}
444
445int sgn(const Rational& a)
446{
447  return mpq_sgn(a.p->rat);
448}
449
450Rational
451abs(const Rational& a)
452{
453  Rational
454    erg;
455
456  if (mpq_sgn(a.p->rat)<0)
457    mpq_neg(erg.p->rat,a.p->rat);
458  else
459    mpq_set(erg.p->rat,a.p->rat);
460  return erg;
461}
462
463Rational gcd( const Rational &a,const Rational &b )
464{
465    if( a == 0 )
466    {
467        if( b == 0 )
468        {
469            return  (Rational)1;
470        }
471        else
472        {
473            return  abs( b );
474        }
475    }
476    else if( b == 0 )
477    {
478        return  abs( a );
479    }
480
481    Rational erg;
482
483    mpz_gcd( mpq_numref( erg.p->rat ),
484            mpq_numref( a.p->rat ),mpq_numref( b.p->rat ) );
485    mpz_gcd( mpq_denref( erg.p->rat ),
486            mpq_denref( a.p->rat ),mpq_denref( b.p->rat ) );
487
488    //mpq_canonicalize( erg.p->rat );
489
490    return  abs( erg );
491}
492
493Rational gcd( Rational *a,int n )
494{
495    if( n == 1 )
496    {
497        return  a[0];
498    }
499
500    Rational g = gcd( a[0],a[1] );
501
502    for( int i=2; i<n; i++ )
503    {
504        g = gcd( g,a[i] );
505    }
506
507    return  g;
508}
509
510Rational lcm( const Rational &a,const Rational &b )
511{
512    if( a == 0 )
513    {
514        return b;
515    }
516    else if( b == 0 )
517    {
518        return a;
519    }
520
521    return a*b/gcd(a,b);
522}
523
524Rational lcm( Rational *a,int n )
525{
526    if( n == 1 )
527    {
528        return  a[0];
529    }
530
531    Rational g = lcm( a[0],a[1] );
532
533    for( int i=2; i<n; i++ )
534    {
535        g = lcm( g,a[i] );
536    }
537
538    return  g;
539}
540
541double  Rational::complexity( ) const
542{
543    double num = mpz_get_d( mpq_numref( p->rat ) );
544    double den = mpz_get_d( mpq_denref( p->rat ) );
545
546    if( num < 0 ) num = -num;
547    if( den < 0 ) den = -den;
548
549    return  ( num > den ? num : den );
550}
551
552#endif /* HAVE_SPECTRUM */
553// ----------------------------------------------------------------------------
554//  GMPrat.cc
555//  end of file
556// ----------------------------------------------------------------------------
Note: See TracBrowser for help on using the repository browser.