source: git/libpolys/coeffs/longrat.h @ fc2acf

spielwiese
Last change on this file since fc2acf was fc2acf, checked in by Oleksandr Motsak <motsak@…>, 8 years ago
Testing correctness in trans ext
  • Property mode set to 100644
File size: 4.0 KB
Line 
1#ifndef LONGRAT_H
2#define LONGRAT_H
3/****************************************
4*  Computer Algebra System SINGULAR     *
5****************************************/
6/*
7* ABSTRACT: computation with long rational numbers
8*/
9#include <misc/auxiliary.h>
10
11#include <coeffs/si_gmp.h>
12#include <coeffs/coeffs.h>
13
14struct snumber; typedef struct snumber  *number;
15
16/*-----------------------------------------------------------------*/
17/**
18**  'SR_INT' is the type of those integers small enough to fit into  29  bits.
19**  Therefor the value range of this small integers is: $-2^{28}...2^{28}-1$.
20**
21**  Small integers are represented by an immediate integer handle, containing
22**  the value instead of pointing  to  it,  which  has  the  following  form:
23**
24**      +-------+-------+-------+-------+- - - -+-------+-------+-------+
25**      | guard | sign  | bit   | bit   |       | bit   | tag   | tag   |
26**      | bit   | bit   | 27    | 26    |       | 0     | 0     | 1     |
27**      +-------+-------+-------+-------+- - - -+-------+-------+-------+
28**
29**  Immediate integers handles carry the tag 'SR_INT', i.e. the last bit is 1.
30**  This distuingishes immediate integers from other handles which  point  to
31**  structures aligned on 4 byte boundaries and therefor have last bit  zero.
32**  (The second bit is reserved as tag to allow extensions of  this  scheme.)
33**  Using immediates as pointers and dereferencing them gives address errors.
34**
35**  To aid overflow check the most significant two bits must always be equal,
36**  that is to say that the sign bit of immediate integers has a  guard  bit.
37**
38**  The macros 'INT_TO_SR' and 'SR_TO_INT' should be used to convert  between
39**  a small integer value and its representation as immediate integer handle.
40**
41**  Large integers and rationals are represented by z and n
42**  where n may be undefined (if s==3)
43**  NULL represents only deleted values
44*/
45
46struct snumber
47{
48  mpz_t z; //< Zaehler
49  mpz_t n; //< Nenner
50#if defined(LDEBUG)
51  int debug;
52#endif
53
54  /**
55   * parameter s in number:
56   * 0 (or FALSE): not normalised rational
57   * 1 (or TRUE):  normalised rational
58   * 3          :  integer with n==NULL
59   **/
60  BOOLEAN s; //< integer parameter
61};
62
63#define SR_HDL(A) ((long)(A))
64
65#define SR_INT    1L
66#define INT_TO_SR(INT)  ((number) (((long)INT << 2) + SR_INT))
67#define SR_TO_INT(SR)   (((long)SR) >> 2)
68
69#define MP_SMALL 1
70
71BOOLEAN nlInitChar(coeffs, void*);
72
73/// only used by slimgb (tgb.cc)
74static  FORCE_INLINE int nlQlogSize (number n, const coeffs r)
75{
76  assume( nCoeff_is_Q (r) );
77
78  long nl=n_Size(n,r);
79  if (nl==0L) return 0;
80  if (nl==1L)
81  {
82    long i = SR_TO_INT (n);
83    unsigned long v;
84    v = (i >= 0) ? i : -i;
85    int r = 0;
86
87    while(v >>= 1)
88    {
89      r++;
90    }
91    return r + 1;
92  }
93  //assume denominator is 0
94  number nn=(number) n;
95  return mpz_sizeinbase (nn->z, 2);
96}
97
98
99static FORCE_INLINE BOOLEAN nlIsInteger(number q, const coeffs r)
100{
101  assume( nCoeff_is_Q (r) );
102  n_Test(q, r);
103 
104  if (SR_HDL(q) & SR_INT)
105    return 1; // immidiate int
106 
107  if( q->s == 3 )
108  {
109    assume( q->n == NULL );
110    return 1; // integer with n==NULL
111  }
112
113  number qq = n_Copy(q, r);
114  number nn = n_GetDenom(qq, r);
115
116  const BOOLEAN ret = n_IsOne(nn, r);
117
118  n_Delete( &nn, r);
119  n_Delete( &qq, r);
120
121  return ret;
122}
123
124number nlModP(number q, const coeffs Q, const coeffs Zp);
125void   nlNormalize(number &x, const coeffs r);
126void   nlInpGcd(number &a, number b, const coeffs r);
127void   nlDelete(number *a, const coeffs r);
128
129
130/// create a rational i/j (implicitly) over Q
131/// NOTE: make sure to use correct Q in debug mode
132number   nlInit2 (int i, int j, const coeffs r);
133
134/// create a rational i/j (implicitly) over Q
135/// NOTE: make sure to use correct Q in debug mode
136number   nlInit2gmp (mpz_t i, mpz_t j, const coeffs r);
137
138// FIXME: TODO:  why only if HAVE_RINGS? bug?
139#  ifdef HAVE_RINGS
140void   nlGMP(number &i, number n, const coeffs r); // to be replaced with n_MPZ(number n, number &i,const coeffs r)???
141number nlMapGMP(number from, const coeffs src, const coeffs dst);
142#  endif
143
144#endif
145
146
Note: See TracBrowser for help on using the repository browser.