source: git/factory/imm.h @ 8a30b1

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