source: git/factory/imm.h @ bebd13f

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