source: git/factory/imm.h @ c1d386

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