source: git/factory/imm.h @ 3940fc5

spielwiese
Last change on this file since 3940fc5 was 3940fc5, checked in by Jens Schmidt <schmidt@…>, 26 years ago
* imm.h: doc fix git-svn-id: file:///usr/local/Singular/svn/trunk@1684 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.15 1998-05-11 10:42:21 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#ifdef WINNT
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
91inline int imm_iszero ( const InternalCF * const ptr )
92{
93    return imm2int( ptr ) == 0;
94}
95
96inline int imm_isone ( const InternalCF * const ptr )
97{
98    return imm2int( ptr ) == 1;
99}
100
101inline int imm_iszero_p ( const InternalCF * const ptr )
102{
103    return imm2int( ptr ) == 0;
104}
105
106inline int imm_isone_p ( const InternalCF * const ptr )
107{
108    return imm2int( ptr ) == 1;
109}
110
111inline int imm_iszero_gf ( const InternalCF * const ptr )
112{
113    return gf_iszero( imm2int( ptr ) );
114}
115
116inline int imm_isone_gf ( const InternalCF * const ptr )
117{
118    return gf_isone( imm2int( ptr ) );
119}
120//}}}
121
122//{{{ conversion functions
123inline int imm_intval ( const InternalCF* const op )
124{
125    if ( is_imm( op ) == FFMARK )
126        if ( cf_glob_switches.isOn( SW_SYMMETRIC_FF ) )
127            return ff_symmetric( imm2int( op ) );
128        else
129            return imm2int( op );
130    else  if ( is_imm( op ) == GFMARK ) {
131        ASSERT( gf_isff( imm2int( op ) ), "invalid conversion" );
132        if ( cf_glob_switches.isOn( SW_SYMMETRIC_FF ) )
133            return ff_symmetric( gf_gf2ff( imm2int( op ) ) );
134        else
135            return gf_gf2ff( imm2int( op ) );
136    }
137    else
138        return imm2int( op );
139}
140//}}}
141
142//{{{ inline int imm_sign ( const InternalCF * const op )
143//{{{ docu
144//
145// imm_sign() - return sign of immediate object.
146//
147// If CO is an immediate integer, the sign is defined as usual.
148// If CO is an element of FF(p) and SW_SYMMETRIC_FF is on the
149// sign of CO is the sign of the symmetric representation of CO.
150// If CO is in GF(q) or in FF(p) and SW_SYMMETRIC_FF is off, the
151// sign of CO is zero iff CO is zero, otherwise the sign is one.
152//
153// See also: CanonicalForm::sign(), gf_sign()
154//
155//}}}
156inline int
157imm_sign ( const InternalCF * const op )
158{
159    if ( is_imm( op ) == FFMARK )
160        if ( imm2int( op ) == 0 )
161            return 0;
162        else  if ( cf_glob_switches.isOn( SW_SYMMETRIC_FF ) )
163            if ( ff_symmetric( imm2int( op ) ) > 0 )
164                return 1;
165            else
166                return -1;
167        else
168            return 1;
169    else  if ( is_imm( op ) == GFMARK )
170        return gf_sign( imm2int( op ) );
171    else  if ( imm2int( op ) == 0 )
172        return 0;
173    else  if ( imm2int( op ) > 0 )
174        return 1;
175    else
176        return -1;
177}
178//}}}
179
180//{{{ inline int imm_cmp, imm_cmp_p, imm_cmp_gf ( const InternalCF * const lhs, const InternalCF * const rhs )
181//{{{ docu
182//
183// imm_cmp(), imm_cmp_p(), imm_cmp_gf() - compare immediate objects.
184//
185// For immediate integers, it is clear how this should be done.
186// For objects from finite fields, it is not clear since they
187// are not ordered fields.  However, since we want to have a
188// total well order on polynomials we have to define a total well
189// order on all coefficients, too.  I decided to use simply the
190// order on the representation as `int's of such objects.
191//
192// See also: CanonicalForm::operator <(), CanonicalForm::operator ==()
193//
194//}}}
195inline int
196imm_cmp ( const InternalCF * const lhs, const InternalCF * const rhs )
197{
198    if ( imm2int( lhs ) == imm2int( rhs ) )
199        return 0;
200    else  if ( imm2int( lhs ) > imm2int( rhs ) )
201        return 1;
202    else
203        return -1;
204}
205
206inline int
207imm_cmp_p ( 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_gf ( const InternalCF * const lhs, const InternalCF * const rhs )
219{
220    if ( imm2int( lhs ) == imm2int( rhs ) )
221        return 0;
222    // check is done in this way because zero should be minimal
223    else if ( imm2int( lhs ) > imm2int( rhs ) )
224        return -1;
225    else
226        return 1;
227}
228//}}}
229
230//{{{ arithmetic operators
231inline InternalCF * imm_add ( const InternalCF * const lhs, const InternalCF * const rhs )
232{
233    int result = imm2int( lhs ) + imm2int( rhs );
234    if ( ( result > MAXIMMEDIATE ) || ( result < MINIMMEDIATE ) )
235        return CFFactory::basic( result );
236    else
237        return int2imm( result );
238}
239
240inline InternalCF * imm_add_p ( const InternalCF * const lhs, const InternalCF * const rhs )
241{
242    return int2imm_p( ff_add( imm2int( lhs ), imm2int( rhs ) ) );
243}
244
245inline InternalCF * imm_add_gf ( const InternalCF * const lhs, const InternalCF * const rhs )
246{
247    return int2imm_gf( gf_add( imm2int( lhs ), imm2int( rhs ) ) );
248}
249
250inline InternalCF * imm_sub ( const InternalCF * const lhs, const InternalCF * const rhs )
251{
252    int result = imm2int( lhs ) - imm2int( rhs );
253    if ( ( result > MAXIMMEDIATE ) || ( result < MINIMMEDIATE ) )
254        return CFFactory::basic( result );
255    else
256        return int2imm( result );
257}
258
259inline InternalCF * imm_sub_p ( const InternalCF * const lhs, const InternalCF * const rhs )
260{
261    return int2imm_p( ff_sub( imm2int( lhs ), imm2int( rhs ) ) );
262}
263
264inline InternalCF * imm_sub_gf ( const InternalCF * const lhs, const InternalCF * const rhs )
265{
266    return int2imm_gf( gf_sub( imm2int( lhs ), imm2int( rhs ) ) );
267}
268
269#ifdef __MWERKS__
270InternalCF * imm_mul ( InternalCF * lhs, InternalCF * rhs );
271#else
272inline InternalCF *
273imm_mul ( InternalCF * lhs, InternalCF * rhs )
274{
275    INT64 result = (INT64)imm2int( lhs ) * imm2int( rhs );
276    if ( ( result > MAXIMMEDIATELL ) || ( result < MINIMMEDIATELL ) ) {
277        InternalCF * res = CFFactory::basic( IntegerDomain, imm2int( lhs ), true );
278        return res->mulcoeff( rhs );
279    }
280    else
281        return int2imm( (int)result );
282}
283#endif /* ! __MWERKS__ */
284
285inline InternalCF * imm_mul_p ( const InternalCF * const lhs, const InternalCF * const rhs )
286{
287    return int2imm_p( ff_mul( imm2int( lhs ), imm2int( rhs ) ) );
288}
289
290inline InternalCF * imm_mul_gf ( const InternalCF * const lhs, const InternalCF * const rhs )
291{
292    return int2imm_gf( gf_mul( imm2int( lhs ), imm2int( rhs ) ) );
293}
294
295inline InternalCF * imm_div ( const InternalCF * const lhs, const InternalCF * const rhs )
296{
297    int a = imm2int( lhs );
298    int b = imm2int( rhs );
299    if ( a > 0 )
300        return int2imm( a / b );
301    else  if ( b > 0 )
302        return int2imm( -((b-a-1)/b) );
303    else
304        return int2imm( (-a-b-1)/(-b) );
305}
306
307inline InternalCF * imm_divrat ( const InternalCF * const lhs, const InternalCF * const rhs )
308{
309    if ( cf_glob_switches.isOn( SW_RATIONAL ) )
310        return CFFactory::rational( imm2int( lhs ), imm2int( rhs ) );
311    else {
312        int a = imm2int( lhs );
313        int b = imm2int( rhs );
314        if ( a > 0 )
315            return int2imm( a / b );
316        else  if ( b > 0 )
317            return int2imm( -((b-a-1)/b) );
318        else
319            return int2imm( (-a-b-1)/(-b) );
320    }
321}
322
323inline InternalCF * imm_div_p ( const InternalCF * const lhs, const InternalCF * const rhs )
324{
325    return int2imm_p( ff_div( imm2int( lhs ), imm2int( rhs ) ) );
326}
327
328inline InternalCF * imm_div_gf ( const InternalCF * const lhs, const InternalCF * const rhs )
329{
330    return int2imm_gf( gf_div( imm2int( lhs ), imm2int( rhs ) ) );
331}
332
333inline InternalCF * imm_mod ( const InternalCF * const lhs, const InternalCF * const rhs )
334{
335    if ( cf_glob_switches.isOn( SW_RATIONAL ) )
336        return int2imm( 0 );
337    else {
338        int a = imm2int( lhs );
339        int b = imm2int( rhs );
340        if ( a > 0 )
341            if ( b > 0 )
342                return int2imm( a % b );
343            else
344                return int2imm( a % (-b) );
345        else
346            if ( b > 0 ) {
347                int r = (-a) % b;
348                return int2imm( (r==0) ? r : b-r );
349            }
350            else {
351                int r = (-a) % (-b);
352                return int2imm( (r==0) ? r : -b-r );
353            }
354    }
355}
356
357inline InternalCF * imm_mod_p ( const InternalCF * const, const InternalCF * const )
358{
359    return int2imm_p( 0 );
360}
361
362inline InternalCF * imm_mod_gf ( const InternalCF * const, const InternalCF * const )
363{
364    return int2imm_gf( gf_q );
365}
366
367inline void imm_divrem ( const InternalCF * const lhs, const InternalCF * const rhs, InternalCF * & q, InternalCF * & r )
368{
369    if ( cf_glob_switches.isOn( SW_RATIONAL ) ) {
370        q = imm_divrat( lhs, rhs );
371        r = CFFactory::basic( 0 );
372    }
373    else {
374        q = imm_div( lhs, rhs );
375        r = imm_mod( lhs, rhs );
376    }
377}
378
379inline void imm_divrem_p ( const InternalCF * const lhs, const InternalCF * const rhs, InternalCF * & q, InternalCF * & r )
380{
381    q = int2imm_p( ff_div( imm2int( lhs ), imm2int( rhs ) ) );
382    r = int2imm_p( 0 );
383}
384
385inline void imm_divrem_gf ( const InternalCF * const lhs, const InternalCF * const rhs, InternalCF * & q, InternalCF * & r )
386{
387    q = int2imm_gf( gf_div( imm2int( lhs ), imm2int( rhs ) ) );
388    r = int2imm_gf( gf_q );
389}
390
391inline InternalCF * imm_neg ( const InternalCF * const op )
392{
393    return int2imm( -imm2int( op ) );
394}
395
396inline InternalCF * imm_neg_p ( const InternalCF * const op )
397{
398    return int2imm_p( ff_neg( imm2int( op ) ) );
399}
400
401inline InternalCF * imm_neg_gf ( const InternalCF * const op )
402{
403    return int2imm_gf( gf_neg( imm2int( op ) ) );
404}
405//}}}
406
407//{{{ input/output
408#ifndef NOSTREAMIO
409inline void imm_print ( ostream & os, const InternalCF * const op, const char * const str )
410{
411    if ( is_imm( op ) == FFMARK )
412        if ( cf_glob_switches.isOn( SW_SYMMETRIC_FF ) )
413            os << ff_symmetric( imm2int( op ) ) << str;
414        else
415            os << imm2int( op ) << str;
416    else  if ( is_imm( op ) == GFMARK ) {
417        gf_print( os, imm2int( op ) );
418        os << str;
419    }
420    else
421        os << imm2int( op ) << str;
422}
423#endif /* NOSTREAMIO */
424//}}}
425
426#endif /* ! INCL_IMM_H */
Note: See TracBrowser for help on using the repository browser.