source: git/factory/imm.h @ c1cd11

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