source: git/factory/imm.h @ 194f5e5

spielwiese
Last change on this file since 194f5e5 was c1784d, checked in by Wilfred Pohl <pohl@…>, 26 years ago
version for Metrowerks git-svn-id: file:///usr/local/Singular/svn/trunk@1370 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.13 1998-04-14 15:15:29 pohl 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
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 * imm_mul ( InternalCF * lhs, InternalCF * rhs )
273{
274    INT64 result = (INT64)imm2int( lhs ) * imm2int( rhs );
275    if ( ( result > MAXIMMEDIATELL ) || ( result < MINIMMEDIATELL ) ) {
276        InternalCF * res = CFFactory::basic( IntegerDomain, imm2int( lhs ), true );
277        return res->mulcoeff( rhs );
278    }
279    else
280        return int2imm( (int)result );
281}
282#endif
283
284inline InternalCF * imm_mul_p ( const InternalCF * const lhs, const InternalCF * const rhs )
285{
286    return int2imm_p( ff_mul( imm2int( lhs ), imm2int( rhs ) ) );
287}
288
289inline InternalCF * imm_mul_gf ( const InternalCF * const lhs, const InternalCF * const rhs )
290{
291    return int2imm_gf( gf_mul( imm2int( lhs ), imm2int( rhs ) ) );
292}
293
294inline InternalCF * imm_div ( const InternalCF * const lhs, const InternalCF * const rhs )
295{
296    int a = imm2int( lhs );
297    int b = imm2int( rhs );
298    if ( a > 0 )
299        return int2imm( a / b );
300    else  if ( b > 0 )
301        return int2imm( -((b-a-1)/b) );
302    else
303        return int2imm( (-a-b-1)/(-b) );
304}
305
306inline InternalCF * imm_divrat ( const InternalCF * const lhs, const InternalCF * const rhs )
307{
308    if ( cf_glob_switches.isOn( SW_RATIONAL ) )
309        return CFFactory::rational( imm2int( lhs ), imm2int( rhs ) );
310    else {
311        int a = imm2int( lhs );
312        int b = imm2int( rhs );
313        if ( a > 0 )
314            return int2imm( a / b );
315        else  if ( b > 0 )
316            return int2imm( -((b-a-1)/b) );
317        else
318            return int2imm( (-a-b-1)/(-b) );
319    }
320}
321
322inline InternalCF * imm_div_p ( const InternalCF * const lhs, const InternalCF * const rhs )
323{
324    return int2imm_p( ff_div( imm2int( lhs ), imm2int( rhs ) ) );
325}
326
327inline InternalCF * imm_div_gf ( const InternalCF * const lhs, const InternalCF * const rhs )
328{
329    return int2imm_gf( gf_div( imm2int( lhs ), imm2int( rhs ) ) );
330}
331
332inline InternalCF * imm_mod ( const InternalCF * const lhs, const InternalCF * const rhs )
333{
334    if ( cf_glob_switches.isOn( SW_RATIONAL ) )
335        return int2imm( 0 );
336    else {
337        int a = imm2int( lhs );
338        int b = imm2int( rhs );
339        if ( a > 0 )
340            if ( b > 0 )
341                return int2imm( a % b );
342            else
343                return int2imm( a % (-b) );
344        else
345            if ( b > 0 ) {
346                int r = (-a) % b;
347                return int2imm( (r==0) ? r : b-r );
348            }
349            else {
350                int r = (-a) % (-b);
351                return int2imm( (r==0) ? r : -b-r );
352            }
353    }
354}
355
356inline InternalCF * imm_mod_p ( const InternalCF * const, const InternalCF * const )
357{
358    return int2imm_p( 0 );
359}
360
361inline InternalCF * imm_mod_gf ( const InternalCF * const, const InternalCF * const )
362{
363    return int2imm_gf( gf_q );
364}
365
366inline void imm_divrem ( const InternalCF * const lhs, const InternalCF * const rhs, InternalCF * & q, InternalCF * & r )
367{
368    if ( cf_glob_switches.isOn( SW_RATIONAL ) ) {
369        q = imm_divrat( lhs, rhs );
370        r = CFFactory::basic( 0 );
371    }
372    else {
373        q = imm_div( lhs, rhs );
374        r = imm_mod( lhs, rhs );
375    }
376}
377
378inline void imm_divrem_p ( const InternalCF * const lhs, const InternalCF * const rhs, InternalCF * & q, InternalCF * & r )
379{
380    q = int2imm_p( ff_div( imm2int( lhs ), imm2int( rhs ) ) );
381    r = int2imm_p( 0 );
382}
383
384inline void imm_divrem_gf ( const InternalCF * const lhs, const InternalCF * const rhs, InternalCF * & q, InternalCF * & r )
385{
386    q = int2imm_gf( gf_div( imm2int( lhs ), imm2int( rhs ) ) );
387    r = int2imm_gf( gf_q );
388}
389
390inline InternalCF * imm_neg ( const InternalCF * const op )
391{
392    return int2imm( -imm2int( op ) );
393}
394
395inline InternalCF * imm_neg_p ( const InternalCF * const op )
396{
397    return int2imm_p( ff_neg( imm2int( op ) ) );
398}
399
400inline InternalCF * imm_neg_gf ( const InternalCF * const op )
401{
402    return int2imm_gf( gf_neg( imm2int( op ) ) );
403}
404//}}}
405
406//{{{ input/output
407#ifndef NOSTREAMIO
408inline void imm_print ( ostream & os, const InternalCF * const op, const char * const str )
409{
410    if ( is_imm( op ) == FFMARK )
411        if ( cf_glob_switches.isOn( SW_SYMMETRIC_FF ) )
412            os << ff_symmetric( imm2int( op ) ) << str;
413        else
414            os << imm2int( op ) << str;
415    else  if ( is_imm( op ) == GFMARK ) {
416        gf_print( os, imm2int( op ) );
417        os << str;
418    }
419    else
420        os << imm2int( op ) << str;
421}
422#endif /* NOSTREAMIO */
423//}}}
424
425#endif /* ! INCL_IMM_H */
Note: See TracBrowser for help on using the repository browser.