source: git/factory/imm.h @ b1d287

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