source: git/factory/imm.h @ f2b01e

spielwiese
Last change on this file since f2b01e was f2b01e, checked in by Jens Schmidt <schmidt@…>, 26 years ago
* imm.h: doc fix git-svn-id: file:///usr/local/Singular/svn/trunk@986 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 10.4 KB
Line 
1/* emacs edit mode for this file is -*- C++ -*- */
2/* $Id: imm.h,v 1.12 1997-12-17 11:10:02 schmidt Exp $ */
3
4#ifndef INCL_IMM_H
5#define INCL_IMM_H
6
7#include <config.h>
8
9#ifndef NOSTREAMIO
10#include <iostream.h>
11#endif /* NOSTREAMIO */
12
13#include "assert.h"
14
15#include "cf_defs.h"
16#include "cf_globals.h"
17#include "ffops.h"
18#include "gfops.h"
19#include "cf_factory.h"
20#include "canonicalform.h"
21#include "int_cf.h"
22
23const int INTMARK = 1;
24const int FFMARK = 2;
25const int GFMARK = 3;
26
27const int MINIMMEDIATE = -268435454; // -2^28-2
28const int MAXIMMEDIATE = 268435454;  // 2^28-2
29#ifdef macintosh
30const INT64 MINIMMEDIATELL = -268435454;
31const INT64 MAXIMMEDIATELL = 268435454;
32#elif defined WINNT
33const INT64 MINIMMEDIATELL = -268435454i64;
34const INT64 MAXIMMEDIATELL = 268435454i64;
35#else
36const INT64 MINIMMEDIATELL = -268435454LL;
37const INT64 MAXIMMEDIATELL = 268435454LL;
38#endif
39
40//{{{ conversion functions
41#ifdef HAS_ARITHMETIC_SHIFT
42
43inline int imm2int ( const InternalCF * const imm )
44{
45    return (int)imm >> 2;
46}
47
48inline InternalCF * int2imm ( int i )
49{
50    return (InternalCF*)((i << 2) | INTMARK );
51}
52
53#else
54
55inline int imm2int ( const InternalCF * const imm )
56{
57    // this could be better done by masking the sign bit
58    if ( (int)imm < 0 )
59        return -((-(int)imm) >> 2);
60    else
61        return (int)imm >> 2;
62}
63
64inline InternalCF * int2imm ( int i )
65{
66    if ( i < 0 )
67        return (InternalCF*)(-(((-i) << 2) | INTMARK));
68    else
69        return (InternalCF*)((i << 2) | INTMARK );
70}
71
72#endif
73
74inline InternalCF * int2imm_p ( int i )
75{
76    return (InternalCF*)((i << 2) | FFMARK );
77}
78
79inline InternalCF * int2imm_gf ( int i )
80{
81    return (InternalCF*)((i << 2) | GFMARK );
82}
83//}}}
84
85//{{{ predicates
86inline int is_imm ( const InternalCF * const ptr )
87{
88    // returns 0 if ptr is not immediate
89    return ( (int)ptr & 3 );
90}
91
92inline int imm_iszero ( const InternalCF * const ptr )
93{
94    return imm2int( ptr ) == 0;
95}
96
97inline int imm_isone ( const InternalCF * const ptr )
98{
99    return imm2int( ptr ) == 1;
100}
101
102inline int imm_iszero_p ( const InternalCF * const ptr )
103{
104    return imm2int( ptr ) == 0;
105}
106
107inline int imm_isone_p ( const InternalCF * const ptr )
108{
109    return imm2int( ptr ) == 1;
110}
111
112inline int imm_iszero_gf ( const InternalCF * const ptr )
113{
114    return gf_iszero( imm2int( ptr ) );
115}
116
117inline int imm_isone_gf ( const InternalCF * const ptr )
118{
119    return gf_isone( imm2int( ptr ) );
120}
121//}}}
122
123//{{{ conversion functions
124inline int imm_intval ( const InternalCF* const op )
125{
126    if ( is_imm( op ) == FFMARK )
127        if ( cf_glob_switches.isOn( SW_SYMMETRIC_FF ) )
128            return ff_symmetric( imm2int( op ) );
129        else
130            return imm2int( op );
131    else  if ( is_imm( op ) == GFMARK ) {
132        ASSERT( gf_isff( imm2int( op ) ), "invalid conversion" );
133        if ( cf_glob_switches.isOn( SW_SYMMETRIC_FF ) )
134            return ff_symmetric( gf_gf2ff( imm2int( op ) ) );
135        else
136            return gf_gf2ff( imm2int( op ) );
137    }
138    else
139        return imm2int( op );
140}
141//}}}
142
143//{{{ inline int imm_sign ( const InternalCF * const op )
144//{{{ docu
145//
146// imm_sign() - return sign of immediate object.
147//
148// If CO is an immediate integer, the sign is defined as usual.
149// If CO is an element of FF(p) and SW_SYMMETRIC_FF is on the
150// sign of CO is the sign of the symmetric representation of CO.
151// If CO is in GF(q) or in FF(p) and SW_SYMMETRIC_FF is off, the
152// sign of CO is zero iff CO is zero, otherwise the sign is one.
153//
154// See also: CanonicalForm::sign(), gf_sign()
155//
156//}}}
157inline int
158imm_sign ( const InternalCF * const op )
159{
160    if ( is_imm( op ) == FFMARK )
161        if ( imm2int( op ) == 0 )
162            return 0;
163        else  if ( cf_glob_switches.isOn( SW_SYMMETRIC_FF ) )
164            if ( ff_symmetric( imm2int( op ) ) > 0 )
165                return 1;
166            else
167                return -1;
168        else
169            return 1;
170    else  if ( is_imm( op ) == GFMARK )
171        return gf_sign( imm2int( op ) );
172    else  if ( imm2int( op ) == 0 )
173        return 0;
174    else  if ( imm2int( op ) > 0 )
175        return 1;
176    else
177        return -1;
178}
179//}}}
180
181//{{{ inline int imm_cmp, imm_cmp_p, imm_cmp_gf ( const InternalCF * const lhs, const InternalCF * const rhs )
182//{{{ docu
183//
184// imm_cmp(), imm_cmp_p(), imm_cmp_gf() - compare immediate objects.
185//
186// For immediate integers, it is clear how this should be done.
187// For objects from finite fields, it is not clear since they
188// are not ordered fields.  However, since we want to have a
189// total well order on polynomials we have to define a total well
190// order on all coefficients, too.  I decided to use simply the
191// order on the representation as `int's of such objects.
192//
193// See also: CanonicalForm::operator <(), CanonicalForm::operator ==()
194//
195//}}}
196inline int
197imm_cmp ( const InternalCF * const lhs, const InternalCF * const rhs )
198{
199    if ( imm2int( lhs ) == imm2int( rhs ) )
200        return 0;
201    else  if ( imm2int( lhs ) > imm2int( rhs ) )
202        return 1;
203    else
204        return -1;
205}
206
207inline int
208imm_cmp_p ( const InternalCF * const lhs, const InternalCF * const rhs )
209{
210    if ( imm2int( lhs ) == imm2int( rhs ) )
211        return 0;
212    else if ( imm2int( lhs ) > imm2int( rhs ) )
213        return 1;
214    else
215        return -1;
216}
217
218inline int
219imm_cmp_gf ( const InternalCF * const lhs, const InternalCF * const rhs )
220{
221    if ( imm2int( lhs ) == imm2int( rhs ) )
222        return 0;
223    // check is done in this way because zero should be minimal
224    else if ( imm2int( lhs ) > imm2int( rhs ) )
225        return -1;
226    else
227        return 1;
228}
229//}}}
230
231//{{{ arithmetic operators
232inline InternalCF * imm_add ( const InternalCF * const lhs, const InternalCF * const rhs )
233{
234    int result = imm2int( lhs ) + imm2int( rhs );
235    if ( ( result > MAXIMMEDIATE ) || ( result < MINIMMEDIATE ) )
236        return CFFactory::basic( result );
237    else
238        return int2imm( result );
239}
240
241inline InternalCF * imm_add_p ( const InternalCF * const lhs, const InternalCF * const rhs )
242{
243    return int2imm_p( ff_add( imm2int( lhs ), imm2int( rhs ) ) );
244}
245
246inline InternalCF * imm_add_gf ( const InternalCF * const lhs, const InternalCF * const rhs )
247{
248    return int2imm_gf( gf_add( imm2int( lhs ), imm2int( rhs ) ) );
249}
250
251inline InternalCF * imm_sub ( const InternalCF * const lhs, const InternalCF * const rhs )
252{
253    int result = imm2int( lhs ) - imm2int( rhs );
254    if ( ( result > MAXIMMEDIATE ) || ( result < MINIMMEDIATE ) )
255        return CFFactory::basic( result );
256    else
257        return int2imm( result );
258}
259
260inline InternalCF * imm_sub_p ( const InternalCF * const lhs, const InternalCF * const rhs )
261{
262    return int2imm_p( ff_sub( imm2int( lhs ), imm2int( rhs ) ) );
263}
264
265inline InternalCF * imm_sub_gf ( const InternalCF * const lhs, const InternalCF * const rhs )
266{
267    return int2imm_gf( gf_sub( imm2int( lhs ), imm2int( rhs ) ) );
268}
269
270inline InternalCF * imm_mul ( InternalCF * lhs, InternalCF * rhs )
271{
272    INT64 result = (INT64)imm2int( lhs ) * imm2int( rhs );
273    if ( ( result > MAXIMMEDIATELL ) || ( result < MINIMMEDIATELL ) ) {
274        InternalCF * res = CFFactory::basic( IntegerDomain, imm2int( lhs ), true );
275        return res->mulcoeff( rhs );
276    }
277    else
278        return int2imm( (int)result );
279}
280
281inline InternalCF * imm_mul_p ( const InternalCF * const lhs, const InternalCF * const rhs )
282{
283    return int2imm_p( ff_mul( imm2int( lhs ), imm2int( rhs ) ) );
284}
285
286inline InternalCF * imm_mul_gf ( const InternalCF * const lhs, const InternalCF * const rhs )
287{
288    return int2imm_gf( gf_mul( imm2int( lhs ), imm2int( rhs ) ) );
289}
290
291inline InternalCF * imm_div ( const InternalCF * const lhs, const InternalCF * const rhs )
292{
293    int a = imm2int( lhs );
294    int b = imm2int( rhs );
295    if ( a > 0 )
296        return int2imm( a / b );
297    else  if ( b > 0 )
298        return int2imm( -((b-a-1)/b) );
299    else
300        return int2imm( (-a-b-1)/(-b) );
301}
302
303inline InternalCF * imm_divrat ( const InternalCF * const lhs, const InternalCF * const rhs )
304{
305    if ( cf_glob_switches.isOn( SW_RATIONAL ) )
306        return CFFactory::rational( imm2int( lhs ), imm2int( rhs ) );
307    else {
308        int a = imm2int( lhs );
309        int b = imm2int( rhs );
310        if ( a > 0 )
311            return int2imm( a / b );
312        else  if ( b > 0 )
313            return int2imm( -((b-a-1)/b) );
314        else
315            return int2imm( (-a-b-1)/(-b) );
316    }
317}
318
319inline InternalCF * imm_div_p ( const InternalCF * const lhs, const InternalCF * const rhs )
320{
321    return int2imm_p( ff_div( imm2int( lhs ), imm2int( rhs ) ) );
322}
323
324inline InternalCF * imm_div_gf ( const InternalCF * const lhs, const InternalCF * const rhs )
325{
326    return int2imm_gf( gf_div( imm2int( lhs ), imm2int( rhs ) ) );
327}
328
329inline InternalCF * imm_mod ( const InternalCF * const lhs, const InternalCF * const rhs )
330{
331    if ( cf_glob_switches.isOn( SW_RATIONAL ) )
332        return int2imm( 0 );
333    else {
334        int a = imm2int( lhs );
335        int b = imm2int( rhs );
336        if ( a > 0 )
337            if ( b > 0 )
338                return int2imm( a % b );
339            else
340                return int2imm( a % (-b) );
341        else
342            if ( b > 0 ) {
343                int r = (-a) % b;
344                return int2imm( (r==0) ? r : b-r );
345            }
346            else {
347                int r = (-a) % (-b);
348                return int2imm( (r==0) ? r : -b-r );
349            }
350    }
351}
352
353inline InternalCF * imm_mod_p ( const InternalCF * const, const InternalCF * const )
354{
355    return int2imm_p( 0 );
356}
357
358inline InternalCF * imm_mod_gf ( const InternalCF * const, const InternalCF * const )
359{
360    return int2imm_gf( gf_q );
361}
362
363inline void imm_divrem ( const InternalCF * const lhs, const InternalCF * const rhs, InternalCF * & q, InternalCF * & r )
364{
365    if ( cf_glob_switches.isOn( SW_RATIONAL ) ) {
366        q = imm_divrat( lhs, rhs );
367        r = CFFactory::basic( 0 );
368    }
369    else {
370        q = imm_div( lhs, rhs );
371        r = imm_mod( lhs, rhs );
372    }
373}
374
375inline void imm_divrem_p ( const InternalCF * const lhs, const InternalCF * const rhs, InternalCF * & q, InternalCF * & r )
376{
377    q = int2imm_p( ff_div( imm2int( lhs ), imm2int( rhs ) ) );
378    r = int2imm_p( 0 );
379}
380
381inline void imm_divrem_gf ( const InternalCF * const lhs, const InternalCF * const rhs, InternalCF * & q, InternalCF * & r )
382{
383    q = int2imm_gf( gf_div( imm2int( lhs ), imm2int( rhs ) ) );
384    r = int2imm_gf( gf_q );
385}
386
387inline InternalCF * imm_neg ( const InternalCF * const op )
388{
389    return int2imm( -imm2int( op ) );
390}
391
392inline InternalCF * imm_neg_p ( const InternalCF * const op )
393{
394    return int2imm_p( ff_neg( imm2int( op ) ) );
395}
396
397inline InternalCF * imm_neg_gf ( const InternalCF * const op )
398{
399    return int2imm_gf( gf_neg( imm2int( op ) ) );
400}
401//}}}
402
403//{{{ input/output
404#ifndef NOSTREAMIO
405inline void imm_print ( ostream & os, const InternalCF * const op, const char * const str )
406{
407    if ( is_imm( op ) == FFMARK )
408        if ( cf_glob_switches.isOn( SW_SYMMETRIC_FF ) )
409            os << ff_symmetric( imm2int( op ) ) << str;
410        else
411            os << imm2int( op ) << str;
412    else  if ( is_imm( op ) == GFMARK ) {
413        gf_print( os, imm2int( op ) );
414        os << str;
415    }
416    else
417        os << imm2int( op ) << str;
418}
419#endif /* NOSTREAMIO */
420//}}}
421
422#endif /* ! INCL_IMM_H */
Note: See TracBrowser for help on using the repository browser.