source: git/libpolys/coeffs/modulop.h @ 55b747

spielwiese
Last change on this file since 55b747 was 55b747, checked in by Hans Schoenemann <hannes@…>, 6 years ago
opt: Z/p arithm.
  • Property mode set to 100644
File size: 4.6 KB
Line 
1#ifndef MODULOP_H
2#define MODULOP_H
3/****************************************
4*  Computer Algebra System SINGULAR     *
5****************************************/
6/*
7* ABSTRACT: numbers modulo p (<=32749)
8*/
9#include "misc/auxiliary.h"
10
11// defines are in struct.h
12// define if a*b is with mod instead of tables
13//#define HAVE_MULT_MOD
14// define if a/b is with mod instead of tables
15//#define HAVE_DIV_MOD
16// define if an if should be used
17//#define HAVE_GENERIC_ADD
18
19// enable large primes (32749 < p < 2^31-)
20#define NV_OPS
21#define NV_MAX_PRIME 32749
22#define FACTORY_MAX_PRIME 536870909
23
24struct n_Procs_s; typedef struct  n_Procs_s  *coeffs;
25struct snumber; typedef struct snumber *   number;
26
27BOOLEAN npInitChar(coeffs r, void* p);
28
29// inline number npMultM(number a, number b, int npPrimeM)
30// // return (a*b)%n
31// {
32//    double ab;
33//    long q, res;
34//
35//    ab = ((double) ((int)a)) * ((double) ((int)b));
36//    q  = (long) (ab/((double) npPrimeM));  // q could be off by (+/-) 1
37//    res = (long) (ab - ((double) q)*((double) npPrimeM));
38//    res += (res >> 31) & npPrimeM;
39//    res -= npPrimeM;
40//    res += (res >> 31) & npPrimeM;
41//    return (number)res;
42// }
43#ifdef HAVE_MULT_MOD
44static inline number npMultM(number a, number b, const coeffs r)
45{
46  return (number)
47    ((((unsigned long) a)*((unsigned long) b)) % ((unsigned long) r->ch));
48}
49static inline void npInpMultM(number &a, number b, const coeffs r)
50{
51  a=(number)
52    ((((unsigned long) a)*((unsigned long) b)) % ((unsigned long) r->ch));
53}
54#else
55static inline number npMultM(number a, number b, const coeffs r)
56{
57  long x = (long)r->npLogTable[(long)a]+ r->npLogTable[(long)b];
58  #ifdef HAVE_GENERIC_ADD
59  if (x>r->npPminus1M) x-=r->npPminus1M;
60  #else
61    x-=r->npPminus1M;
62    #if SIZEOF_LONG == 8
63     x += (x >> 63) & r->npPminus1M;
64    #else
65     x += (x >> 31) & r->npPminus1M;
66    #endif
67  #endif
68  return (number)(long)r->npExpTable[x];
69}
70static inline void npInpMultM(number &a, number b, const coeffs r)
71{
72  long x = (long)r->npLogTable[(long)a]+ r->npLogTable[(long)b];
73  #ifdef HAVE_GENERIC_ADD
74  if (x>r->npPminus1M) x-=r->npPminus1M;
75  #else
76    x-=r->npPminus1M;
77    #if SIZEOF_LONG == 8
78     x += (x >> 63) & r->npPminus1M;
79    #else
80     x += (x >> 31) & r->npPminus1M;
81    #endif
82  #endif
83  a=(number)(long)r->npExpTable[x];
84}
85#endif
86
87#if 0
88inline number npAddAsm(number a, number b, int m)
89{
90  number r;
91    asm ("addl %2, %1; cmpl %3, %1; jb 0f; subl %3, %1; 0:"
92         : "=&r" (r)
93         : "%0" (a), "g" (b), "g" (m)
94         : "cc");
95  return r;
96}
97inline number npSubAsm(number a, number b, int m)
98{
99  number r;
100  asm ("subl %2, %1; jnc 0f; addl %3, %1; 0:"
101        : "=&r" (r)
102        : "%0" (a), "g" (b), "g" (m)
103        : "cc");
104  return r;
105}
106#endif
107#ifdef HAVE_GENERIC_ADD
108static inline number npAddM(number a, number b, const coeffs r)
109{
110  unsigned long R = (unsigned long)a + (unsigned long)b;
111  return (number)(R >= r->ch ? R - r->ch : R);
112}
113static inline void npInpAddM(number &a, number b, const coeffs r)
114{
115  unsigned long R = (unsigned long)a + (unsigned long)b;
116  a=(number)(R >= r->ch ? R - r->ch : R);
117}
118static inline number npSubM(number a, number b, const coeffs r)
119{
120  return (number)((long)a<(long)b ?
121                       r->ch-(long)b+(long)a : (long)a-(long)b);
122}
123#else
124static inline number npAddM(number a, number b, const coeffs r)
125{
126   unsigned long res = (long)((unsigned long)a + (unsigned long)b);
127   res -= r->ch;
128#if SIZEOF_LONG == 8
129   res += ((long)res >> 63) & r->ch;
130#else
131   res += ((long)res >> 31) & r->ch;
132#endif
133   return (number)res;
134}
135static inline void npInpAddM(number &a, number b, const coeffs r)
136{
137   unsigned long res = (long)((unsigned long)a + (unsigned long)b);
138   res -= r->ch;
139#if SIZEOF_LONG == 8
140   res += ((long)res >> 63) & r->ch;
141#else
142   res += ((long)res >> 31) & r->ch;
143#endif
144   a=(number)res;
145}
146static inline number npSubM(number a, number b, const coeffs r)
147{
148   long res = ((long)a - (long)b);
149#if SIZEOF_LONG == 8
150   res += (res >> 63) & r->ch;
151#else
152   res += (res >> 31) & r->ch;
153#endif
154   return (number)res;
155}
156#endif
157
158static inline number npNegM(number a, const coeffs r)
159{
160  return (number)((long)(r->ch)-(long)(a));
161}
162
163static inline BOOLEAN npIsZeroM (number  a, const coeffs)
164{
165  return 0 == (long)a;
166}
167
168// inline number npMultM(number a, number b, int npPrimeM)
169// {
170//   return (number)(((long)a*(long)b) % npPrimeM);
171// }
172
173// The folloing is reused inside gnumpc.cc, gnumpfl.cc and longrat.cc
174long    npInt         (number &n, const coeffs r);
175
176// The following is currently used in OPAE.cc, OPAEQ.cc and OPAEp.cc for setting their SetMap...
177nMapFunc npSetMap(const coeffs src, const coeffs dst); // FIXME! BUG?
178
179#define npEqualM(A,B,r)  ((A)==(B))
180
181
182#endif
Note: See TracBrowser for help on using the repository browser.