source: git/factory/imm.h @ 021751

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