source: git/factory/imm.h @ fd68165

spielwiese
Last change on this file since fd68165 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
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
[1afbfe]6#include <stdint.h>
7
[e4fe2b]8// #include "config.h"
[5ec695]9
[bb20e7]10#ifndef NOSTREAMIO
[1dc616]11#ifdef HAVE_IOSTREAM
12#include <iostream>
[181148]13#define OSTREAM std::ostream
[1dc616]14#elif defined(HAVE_IOSTREAM_H)
[bb20e7]15#include <iostream.h>
[181148]16#define OSTREAM ostream
[1dc616]17#endif
[bb20e7]18#endif /* NOSTREAMIO */
19
[650f2d8]20#include "cf_assert.h"
[bb20e7]21
[2dd068]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
[8710ff0]30const long INTMARK = 1;
31const long FFMARK = 2;
32const long GFMARK = 3;
[2dd068]33
[e76d7a6]34/* define type of your compilers 64 bit integer type */
[fd68165]35#ifndef FACTORY_INT64
36#define FACTORY_INT64 long long int
[e76d7a6]37#endif
38
[8710ff0]39#if SIZEOF_LONG == 4
[18ccf2]40const long MINIMMEDIATE = -268435454; // -2^28+2
[8710ff0]41const long MAXIMMEDIATE = 268435454;  // 2^28-2
42#else
[18ccf2]43const long MINIMMEDIATE = -(1L<<60)+2L; // -2^60+2
[8710ff0]44const long MAXIMMEDIATE = (1L<<60)-2L;  // 2^60-2
45#endif
46
[049c4f]47#if defined(WINNT) && ! defined(__GNUC__)
[fd68165]48const FACTORY_INT64 MINIMMEDIATELL = -268435454i64;
49const FACTORY_INT64 MAXIMMEDIATELL = 268435454i64;
[874d40]50#else
[fd68165]51const FACTORY_INT64 MINIMMEDIATELL = -268435454LL;
52const FACTORY_INT64 MAXIMMEDIATELL = 268435454LL;
[874d40]53#endif
[2dd068]54
[07d8d4]55//{{{ conversion functions
[1bc850]56//#ifdef HAS_ARITHMETIC_SHIFT
57#if 1
[2dd068]58
[8710ff0]59inline long imm2int ( const InternalCF * const imm )
[2dd068]60{
[564e39]61    return ((intptr_t)imm) >> 2;
[2dd068]62}
63
[8710ff0]64inline InternalCF * int2imm ( long i )
[2dd068]65{
[8e4601]66    return (InternalCF*)((i << 2) | INTMARK );
[2dd068]67}
68
69#else
70
71inline int imm2int ( const InternalCF * const imm )
72{
73    // this could be better done by masking the sign bit
[564e39]74    if ( ((int)((intptr_t)imm)) < 0 )
75        return -((-(intptr_t)imm) >> 2);
[2dd068]76    else
[564e39]77        return (intptr_t)imm >> 2;
[2dd068]78}
79
[8710ff0]80inline InternalCF * int2imm ( long i )
[2dd068]81{
82    if ( i < 0 )
[8e4601]83        return (InternalCF*)(-(((-i) << 2) | INTMARK));
[2dd068]84    else
[8e4601]85        return (InternalCF*)((i << 2) | INTMARK );
[2dd068]86}
87
88#endif
89
[8710ff0]90inline InternalCF * int2imm_p ( long i )
[2dd068]91{
[8e4601]92    return (InternalCF*)((i << 2) | FFMARK );
[2dd068]93}
94
[8710ff0]95inline InternalCF * int2imm_gf ( long i )
[2dd068]96{
[8e4601]97    return (InternalCF*)((i << 2) | GFMARK );
[2dd068]98}
[ddc27d8]99//}}}
100
[511e63e]101// predicates
[740d7f]102#if 0
[ddc27d8]103inline int is_imm ( const InternalCF * const ptr )
104{
105    // returns 0 if ptr is not immediate
[564e39]106    return ( (intptr_t)ptr & 3 );
[ddc27d8]107}
[740d7f]108#endif
[ddc27d8]109
[511e63e]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 )
[ddc27d8]114{
[511e63e]115    return imm2int( ptr ) == 1;
[ddc27d8]116}
117
[511e63e]118inline int
119imm_isone_p ( const InternalCF * const ptr )
[ddc27d8]120{
121    return imm2int( ptr ) == 1;
122}
[2dd068]123
[511e63e]124inline int
125imm_isone_gf ( const InternalCF * const ptr )
[ddc27d8]126{
[511e63e]127    return gf_isone( imm2int( ptr ) );
[ddc27d8]128}
[511e63e]129//}}}
[ddc27d8]130
[511e63e]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 )
[ddc27d8]135{
[511e63e]136    return imm2int( ptr ) == 0;
[ddc27d8]137}
138
[511e63e]139inline int
140imm_iszero_p ( const InternalCF * const ptr )
[ddc27d8]141{
[511e63e]142    return imm2int( ptr ) == 0;
[ddc27d8]143}
144
[511e63e]145inline int
146imm_iszero_gf ( const InternalCF * const ptr )
[ddc27d8]147{
[511e63e]148    return gf_iszero( imm2int( ptr ) );
[ddc27d8]149}
150//}}}
151
152//{{{ conversion functions
[8710ff0]153inline long imm_intval ( const InternalCF* const op )
[2dd068]154{
[07d8d4]155    if ( is_imm( op ) == FFMARK )
[5bb462]156        if ( cf_glob_switches.isOn( SW_SYMMETRIC_FF ) )
157            return ff_symmetric( imm2int( op ) );
158        else
159            return imm2int( op );
[07d8d4]160    else  if ( is_imm( op ) == GFMARK ) {
[5bb462]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 ) );
[07d8d4]166    }
167    else
[5bb462]168        return imm2int( op );
[2dd068]169}
[07d8d4]170//}}}
[2dd068]171
[07d8d4]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.
[ddc27d8]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.
[07d8d4]182//
[f2b01e]183// See also: CanonicalForm::sign(), gf_sign()
[07d8d4]184//
185//}}}
186inline int
187imm_sign ( const InternalCF * const op )
[2dd068]188{
[07d8d4]189    if ( is_imm( op ) == FFMARK )
[5bb462]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;
[07d8d4]199    else  if ( is_imm( op ) == GFMARK )
[5bb462]200        return gf_sign( imm2int( op ) );
[07d8d4]201    else  if ( imm2int( op ) == 0 )
[5bb462]202        return 0;
[07d8d4]203    else  if ( imm2int( op ) > 0 )
[5bb462]204        return 1;
[07d8d4]205    else
[5bb462]206        return -1;
[2dd068]207}
[07d8d4]208//}}}
[2dd068]209
[ec250c]210//{{{ inline int imm_cmp, imm_cmp_p, imm_cmp_gf ( const InternalCF * const lhs, const InternalCF * const rhs )
[5679256]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//
[f2b01e]222// See also: CanonicalForm::operator <(), CanonicalForm::operator ==()
223//
[5679256]224//}}}
[ec250c]225inline int
226imm_cmp ( const InternalCF * const lhs, const InternalCF * const rhs )
[2dd068]227{
228    if ( imm2int( lhs ) == imm2int( rhs ) )
[5bb462]229        return 0;
[2dd068]230    else  if ( imm2int( lhs ) > imm2int( rhs ) )
[5bb462]231        return 1;
[2dd068]232    else
[5bb462]233        return -1;
[2dd068]234}
235
[ec250c]236inline int
237imm_cmp_p ( const InternalCF * const lhs, const InternalCF * const rhs )
[2dd068]238{
239    if ( imm2int( lhs ) == imm2int( rhs ) )
[5bb462]240        return 0;
[5c1f1a]241    else if ( imm2int( lhs ) > imm2int( rhs ) )
[5bb462]242        return 1;
[5c1f1a]243    else
[5bb462]244        return -1;
[2dd068]245}
246
[ec250c]247inline int
248imm_cmp_gf ( const InternalCF * const lhs, const InternalCF * const rhs )
[2dd068]249{
250    if ( imm2int( lhs ) == imm2int( rhs ) )
[5bb462]251        return 0;
[5c1f1a]252    // check is done in this way because zero should be minimal
253    else if ( imm2int( lhs ) > imm2int( rhs ) )
[5bb462]254        return -1;
[2dd068]255    else
[5bb462]256        return 1;
[2dd068]257}
[07d8d4]258//}}}
[2dd068]259
[07d8d4]260//{{{ arithmetic operators
[2dd068]261inline InternalCF * imm_add ( const InternalCF * const lhs, const InternalCF * const rhs )
262{
[8710ff0]263    long result = imm2int( lhs ) + imm2int( rhs );
[2dd068]264    if ( ( result > MAXIMMEDIATE ) || ( result < MINIMMEDIATE ) )
[5bb462]265        return CFFactory::basic( result );
[2dd068]266    else
[5bb462]267        return int2imm( result );
[2dd068]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{
[8710ff0]282    long result = imm2int( lhs ) - imm2int( rhs );
[2dd068]283    if ( ( result > MAXIMMEDIATE ) || ( result < MINIMMEDIATE ) )
[5bb462]284        return CFFactory::basic( result );
[2dd068]285    else
[5bb462]286        return int2imm( result );
[2dd068]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
[3940fc5]299inline InternalCF *
300imm_mul ( InternalCF * lhs, InternalCF * rhs )
[2dd068]301{
[8710ff0]302    long a = imm2int( lhs );
303    long b = imm2int( rhs );
[18ccf2]304    int sa= 1;
[fd68165]305    unsigned FACTORY_INT64 aa, bb;
[18ccf2]306    if (a < 0)
307    {
308      sa= -1;
[fd68165]309      aa= (unsigned FACTORY_INT64) (-a);
[18ccf2]310    }
311    else
[fd68165]312      aa= (unsigned FACTORY_INT64) a;
[18ccf2]313    if (b < 0)
314    {
315      sa= -sa;
[fd68165]316      bb= (unsigned FACTORY_INT64) (-b);
[18ccf2]317    }
318    else
[fd68165]319      bb= (unsigned FACTORY_INT64) b;
320    unsigned FACTORY_INT64 result = aa*bb;
[314f0a2]321    #if SIZEOF_LONG == 4
[fd68165]322    if (result>(unsigned FACTORY_INT64)MAXIMMEDIATE)
[314f0a2]323    {
324        InternalCF * res = CFFactory::basic( IntegerDomain, a, true );
325        return res->mulcoeff( rhs );
326    }
327    #else
[fd68165]328    if ( ( a!=0L ) && ((result/aa!=bb) || (result>(unsigned FACTORY_INT64) MAXIMMEDIATE) ))
[8710ff0]329    {
330        InternalCF * res = CFFactory::basic( IntegerDomain, a, true );
[5bb462]331        return res->mulcoeff( rhs );
[2dd068]332    }
[314f0a2]333    #endif
[2dd068]334    else
[18ccf2]335      return int2imm( sa*result );
[2dd068]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{
[8710ff0]350    long a = imm2int( lhs );
351    long b = imm2int( rhs );
[2dd068]352    if ( a > 0 )
[5bb462]353        return int2imm( a / b );
[2dd068]354    else  if ( b > 0 )
[5bb462]355        return int2imm( -((b-a-1)/b) );
[2dd068]356    else
[5bb462]357        return int2imm( (-a-b-1)/(-b) );
[2dd068]358}
359
360inline InternalCF * imm_divrat ( const InternalCF * const lhs, const InternalCF * const rhs )
361{
362    if ( cf_glob_switches.isOn( SW_RATIONAL ) )
[5bb462]363        return CFFactory::rational( imm2int( lhs ), imm2int( rhs ) );
[2dd068]364    else {
[8710ff0]365        long a = imm2int( lhs );
366        long b = imm2int( rhs );
[5bb462]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) );
[2dd068]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 ) )
[5bb462]389        return int2imm( 0 );
[2dd068]390    else {
[8710ff0]391        long a = imm2int( lhs );
392        long b = imm2int( rhs );
[5bb462]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 ) {
[8710ff0]400                long r = (-a) % b;
[5bb462]401                return int2imm( (r==0) ? r : b-r );
402            }
403            else {
[8710ff0]404                long r = (-a) % (-b);
[5bb462]405                return int2imm( (r==0) ? r : -b-r );
406            }
[2dd068]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 ) ) {
[5bb462]423        q = imm_divrat( lhs, rhs );
[8710ff0]424        r = CFFactory::basic( 0L );
[2dd068]425    }
426    else {
[5bb462]427        q = imm_div( lhs, rhs );
428        r = imm_mod( lhs, rhs );
[2dd068]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
[511e63e]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 )
[2dd068]448{
449    return int2imm( -imm2int( op ) );
450}
451
[511e63e]452inline InternalCF *
453imm_neg_p ( const InternalCF * const op )
[2dd068]454{
455    return int2imm_p( ff_neg( imm2int( op ) ) );
456}
457
[511e63e]458inline InternalCF *
459imm_neg_gf ( const InternalCF * const op )
[2dd068]460{
461    return int2imm_gf( gf_neg( imm2int( op ) ) );
462}
[07d8d4]463//}}}
[511e63e]464//}}}
[2dd068]465
[07d8d4]466//{{{ input/output
[bb20e7]467#ifndef NOSTREAMIO
[181148]468inline void imm_print ( OSTREAM & os, const InternalCF * const op, const char * const str )
[2dd068]469{
470    if ( is_imm( op ) == FFMARK )
[5bb462]471        if ( cf_glob_switches.isOn( SW_SYMMETRIC_FF ) )
472            os << ff_symmetric( imm2int( op ) ) << str;
473        else
474            os << imm2int( op ) << str;
[2dd068]475    else  if ( is_imm( op ) == GFMARK ) {
[5bb462]476        gf_print( os, imm2int( op ) );
477        os << str;
[2dd068]478    }
479    else
[5bb462]480        os << imm2int( op ) << str;
[2dd068]481}
[bb20e7]482#endif /* NOSTREAMIO */
[7bac09]483//}}}
[bb20e7]484
[493c477]485#endif /* ! INCL_IMM_H */
Note: See TracBrowser for help on using the repository browser.