source: git/kernel/modulop.h @ 098f98f

spielwiese
Last change on this file since 098f98f was 493225, checked in by Hans Schönemann <hannes@…>, 14 years ago
nWrite indep. from currRing git-svn-id: file:///usr/local/Singular/svn/trunk@12377 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • 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/* $Id$ */
7/*
8* ABSTRACT: numbers modulo p (<=32003)
9*/
10#include "structs.h"
11
12// defines are in struct.h
13// define if a*b is with mod instead of tables
14//#define HAVE_MULT_MOD
15// define if a/b is with mod instead of tables
16//#define HAVE_DIV_MOD
17// define if an if should be used
18//#define HAVE_GENERIC_ADD
19
20// enable large primes (32003 < p < 2^31-)
21#define NV_OPS
22#define NV_MAX_PRIME 32003
23
24extern long npPrimeM;
25extern int npGen;
26extern long npMapPrime;
27
28BOOLEAN npGreaterZero (number k);
29number  npMult        (number a, number b);
30number  npInit        (int i, const ring r);
31int     npInt         (number &n, const ring r);
32number  npAdd         (number a, number b);
33number  npSub         (number a, number b);
34void    npPower       (number a, int i, number * result);
35BOOLEAN npIsZero      (number a);
36BOOLEAN npIsOne       (number a);
37BOOLEAN npIsMOne       (number a);
38number  npDiv         (number a, number b);
39number  npNeg         (number c);
40number  npInvers      (number c);
41BOOLEAN npGreater     (number a, number b);
42BOOLEAN npEqual       (number a, number b);
43void    npWrite       (number &a, const ring r);
44const char *  npRead  (const char *s, number *a);
45#ifdef LDEBUG
46BOOLEAN npDBTest      (number a, const char *f, const int l);
47#define npTest(A)     npDBTest(A,__FILE__,__LINE__)
48#else
49#define npTest(A)     (0)
50#endif
51void    npSetChar(int c, ring r);
52void    npInitChar(int c, ring r);
53
54//int     npGetChar();
55
56nMapFunc npSetMap(const ring src, const ring dst);
57number  npMapP(number from);
58number  npMap0(number from);
59/*-------specials for spolys, do NOT use otherwise--------------------------*/
60/* for npMultM, npSubM, npNegM, npEqualM : */
61#ifdef HAVE_DIV_MOD
62extern CARDINAL *npInvTable;
63#else
64#ifndef HAVE_MULT_MOD
65extern long npPminus1M;
66extern CARDINAL *npExpTable;
67extern CARDINAL *npLogTable;
68#endif
69#endif
70
71#if 0
72inline number npMultM(number a, number b)
73// return (a*b)%n
74{
75   double ab;
76   long q, res;
77
78   ab = ((double) ((int)a)) * ((double) ((int)b));
79   q  = (long) (ab/((double) npPrimeM));  // q could be off by (+/-) 1
80   res = (long) (ab - ((double) q)*((double) npPrimeM));
81   res += (res >> 31) & npPrimeM;
82   res -= npPrimeM;
83   res += (res >> 31) & npPrimeM;
84   return (number)res;
85}
86#endif
87#ifdef HAVE_MULT_MOD
88static inline number npMultM(number a, number b)
89{
90  return (number) 
91    ((((unsigned long) a)*((unsigned long) b)) % ((unsigned long) npPrimeM));
92}
93#else
94static inline number npMultM(number a, number b)
95{
96  long x = (long)npLogTable[(long)a]+npLogTable[(long)b];
97  return (number)(long)npExpTable[x<npPminus1M ? x : x-npPminus1M];
98}
99#endif
100
101#if 0
102inline number npAddAsm(number a, number b, int m)
103{
104  number r;
105    asm ("addl %2, %1; cmpl %3, %1; jb 0f; subl %3, %1; 0:"
106         : "=&r" (r)
107         : "%0" (a), "g" (b), "g" (m)
108         : "cc");
109  return r;
110}
111inline number npSubAsm(number a, number b, int m)
112{
113  number r;
114  asm ("subl %2, %1; jnc 0f; addl %3, %1; 0:"
115        : "=&r" (r)
116        : "%0" (a), "g" (b), "g" (m)
117        : "cc");
118  return r;
119}
120#endif
121#ifdef HAVE_GENERIC_ADD
122static inline number npAddM(number a, number b)
123{
124  long r = (long)a + (long)b;
125  return (number)(r >= npPrimeM ? r - npPrimeM : r);
126}
127static inline number npSubM(number a, number b)
128{
129  return (number)((long)a<(long)b ?
130                       npPrimeM-(long)b+(long)a : (long)a-(long)b);
131}
132#else
133static inline number npAddM(number a, number b)
134{
135   long res = ((long)a + (long)b);
136   res -= npPrimeM;
137#if SIZEOF_LONG == 8
138   res += (res >> 63) & npPrimeM;
139#else
140   res += (res >> 31) & npPrimeM;
141#endif
142   return (number)res;
143}
144static inline number npSubM(number a, number b)
145{
146   long res = ((long)a - (long)b);
147#if SIZEOF_LONG == 8
148   res += (res >> 63) & npPrimeM;
149#else
150   res += (res >> 31) & npPrimeM;
151#endif
152   return (number)res;
153}
154#endif
155
156static inline BOOLEAN npIsZeroM (number  a)
157{
158  return 0 == (long)a;
159}
160
161/*
162*inline number npMultM(number a, number b)
163*{
164*  return (number)(((long)a*(long)b) % npPrimeM);
165*}
166*/
167
168#define npNegM(A)      (number)(npPrimeM-(long)(A))
169#define npEqualM(A,B)  ((A)==(B))
170
171
172#ifdef NV_OPS
173static inline number nvMultM(number a, number b)
174{
175#if SIZEOF_LONG == 4
176#define ULONG64 (unsigned long long)(unsigned long)
177#else
178#define ULONG64 (unsigned long)
179#endif
180  return (number) 
181    (unsigned long)((ULONG64 a)*(ULONG64 b) % (ULONG64 npPrimeM));
182}
183number  nvMult        (number a, number b);
184number  nvDiv         (number a, number b);
185number  nvInvers      (number c);
186void    nvPower       (number a, int i, number * result);
187#endif
188
189#endif
Note: See TracBrowser for help on using the repository browser.