[BACK]Return to bf.c CVS log [TXT][DIR] Up to [local] / OpenXM_contrib2 / asir2018 / engine

Annotation of OpenXM_contrib2/asir2018/engine/bf.c, Revision 1.1

1.1     ! noro        1: /*
        !             2:  * $OpenXM$
        !             3:  */
        !             4: #include "ca.h"
        !             5: #include "base.h"
        !             6: #include <math.h>
        !             7:
        !             8: extern int mpfr_roundmode;
        !             9:
        !            10: Num tobf(Num,int);
        !            11:
        !            12: #define BFPREC(a) (BDY((BF)(a))->_mpfr_prec)
        !            13:
        !            14: void strtobf(char *s,BF *p)
        !            15: {
        !            16:   BF r;
        !            17:   NEWBF(r);
        !            18:   mpfr_init(BDY(r));
        !            19:   mpfr_set_str(BDY(r),s,10,mpfr_roundmode);
        !            20:   *p = r;
        !            21: }
        !            22:
        !            23: double mpfrtodbl(mpfr_t a)
        !            24: {
        !            25:   return mpfr_get_d(a,mpfr_roundmode);
        !            26: }
        !            27:
        !            28: Num tobf(Num a,int prec)
        !            29: {
        !            30:   mpfr_t r;
        !            31:   mpz_t z;
        !            32:   mpq_t q;
        !            33:   BF d;
        !            34:   C c;
        !            35:   Num re,im;
        !            36:   int sgn;
        !            37:
        !            38:   if ( !a ) {
        !            39:     prec ? mpfr_init2(r,prec) : mpfr_init(r);
        !            40:     mpfr_set_zero(r,1);
        !            41:     MPFRTOBF(r,d);
        !            42:     return (Num)d;
        !            43:   } else {
        !            44:     switch ( NID(a) ) {
        !            45:     case N_B:
        !            46:       return a;
        !            47:       break;
        !            48:     case N_R:
        !            49:       prec ? mpfr_init2(r,prec) : mpfr_init(r);
        !            50:       mpfr_init_set_d(r,BDY((Real)a),mpfr_roundmode);
        !            51:       MPFRTOBF(r,d);
        !            52:       return (Num)d;
        !            53:       break;
        !            54:     case N_Q:
        !            55:       if ( INT(a) )
        !            56:         mpfr_init_set_z(r,BDY((Z)a),mpfr_roundmode);
        !            57:       else
        !            58:         mpfr_init_set_q(r,BDY((Q)a),mpfr_roundmode);
        !            59:       MPFRTOBF(r,d);
        !            60:       return (Num)d;
        !            61:       break;
        !            62:     case N_C:
        !            63:       re = tobf(((C)a)->r,prec); im = tobf(((C)a)->i,prec);
        !            64:       NEWC(c); c->r = re; c->i = im;
        !            65:       return (Num)c;
        !            66:       break;
        !            67:     default:
        !            68:       error("tobf : invalid argument");
        !            69:       return 0;
        !            70:       break;
        !            71:     }
        !            72:   }
        !            73: }
        !            74:
        !            75: void addbf(Num a,Num b,Num *c)
        !            76: {
        !            77:   mpfr_t r;
        !            78:   BF d;
        !            79:
        !            80:   if ( !a )
        !            81:     *c = b;
        !            82:   else if ( !b )
        !            83:     *c = a;
        !            84:   else if ( (NID(a) <= N_R) && (NID(b) <= N_R ) )
        !            85:     (*addnumt[MAX(NID(a),NID(b))])(a,b,c);
        !            86:   else if ( NID(a) == N_B ) {
        !            87:     switch ( NID(b) ) {
        !            88:     case N_Q:
        !            89:       mpfr_init2(r,BFPREC(a));
        !            90:       if ( INT(b) )
        !            91:         mpfr_add_z(r,BDY((BF)a),BDY((Z)b),mpfr_roundmode);
        !            92:       else
        !            93:         mpfr_add_q(r,BDY((BF)a),BDY((Q)b),mpfr_roundmode);
        !            94:       break;
        !            95:     case N_R:
        !            96:       /* double precision = 53 */
        !            97:       mpfr_init2(r,MAX(BFPREC(a),53));
        !            98:       mpfr_add_d(r,BDY((BF)a),BDY((Real)b),mpfr_roundmode);
        !            99:       break;
        !           100:     case N_B:
        !           101:       mpfr_init2(r,MAX(BFPREC(a),BFPREC(b)));
        !           102:       mpfr_add(r,BDY((BF)a),BDY((BF)b),mpfr_roundmode);
        !           103:       break;
        !           104:     default:
        !           105:       goto err;
        !           106:       break;
        !           107:     }
        !           108:     MPFRTOBF(r,d);
        !           109:     *c = (Num)d;
        !           110:   } else if ( NID(b) == N_B ) {
        !           111:     switch ( NID(a) ) {
        !           112:     case N_Q:
        !           113:       mpfr_init2(r,BFPREC(b));
        !           114:       if ( INT(a) )
        !           115:         mpfr_add_z(r,BDY((BF)b),BDY((Z)a),mpfr_roundmode);
        !           116:       else
        !           117:         mpfr_add_q(r,BDY((BF)b),BDY((Q)a),mpfr_roundmode);
        !           118:       break;
        !           119:     case N_R:
        !           120:       /* double precision = 53 */
        !           121:       mpfr_init2(r,MAX(BFPREC(b),53));
        !           122:       mpfr_add_d(r,BDY((BF)b),BDY((Real)a),mpfr_roundmode);
        !           123:       break;
        !           124:     default:
        !           125:       goto err;
        !           126:       break;
        !           127:     }
        !           128:     MPFRTOBF(r,d);
        !           129:     *c = (Num)d;
        !           130:   } else
        !           131:     goto err;
        !           132:   if ( !cmpbf(*c,0) ) *c = 0;
        !           133:   return;
        !           134:
        !           135: err: error("addbf : invalid argument");
        !           136: }
        !           137:
        !           138: void subbf(Num a,Num b,Num *c)
        !           139: {
        !           140:   mpfr_t r,s;
        !           141:   BF d;
        !           142:
        !           143:   if ( !a )
        !           144:     (*chsgnnumt[NID(b)])(b,c);
        !           145:   else if ( !b )
        !           146:     *c = a;
        !           147:   else if ( (NID(a) <= N_R) && (NID(b) <= N_R ) )
        !           148:     (*subnumt[MAX(NID(a),NID(b))])(a,b,c);
        !           149:   else if ( NID(a) == N_B ) {
        !           150:     switch ( NID(b) ) {
        !           151:     case N_Q:
        !           152:       mpfr_init2(r,BFPREC(a));
        !           153:       if ( INT(b) )
        !           154:         mpfr_sub_z(r,BDY((BF)a),BDY((Z)b),mpfr_roundmode);
        !           155:       else
        !           156:         mpfr_sub_q(r,BDY((BF)a),BDY((Q)b),mpfr_roundmode);
        !           157:       break;
        !           158:     case N_R:
        !           159:       /* double precision = 53 */
        !           160:       mpfr_init2(r,MAX(BFPREC(a),53));
        !           161:       mpfr_sub_d(r,BDY((BF)a),BDY((Real)b),mpfr_roundmode);
        !           162:       break;
        !           163:     case N_B:
        !           164:       mpfr_init2(r,MAX(BFPREC(a),BFPREC(b)));
        !           165:       mpfr_sub(r,BDY((BF)a),BDY((BF)b),mpfr_roundmode);
        !           166:       break;
        !           167:     default:
        !           168:       goto err;
        !           169:     }
        !           170:     MPFRTOBF(r,d);
        !           171:     *c = (Num)d;
        !           172:   } else if ( NID(b)==N_B ) {
        !           173:     switch ( NID(a) ) {
        !           174:     case N_Q:
        !           175:       mpfr_init2(r,BFPREC(b));
        !           176:       if ( INT(a) )
        !           177:         mpfr_sub_z(r,BDY((BF)b),BDY((Z)a),mpfr_roundmode);
        !           178:       else
        !           179:         mpfr_sub_q(r,BDY((BF)b),BDY((Q)a),mpfr_roundmode);
        !           180:       mpfr_neg(r,r,mpfr_roundmode);
        !           181:       break;
        !           182:     case N_R:
        !           183:       /* double precision = 53 */
        !           184:       mpfr_init2(r,MAX(BFPREC(b),53));
        !           185:       mpfr_d_sub(r,BDY((Real)a),BDY((BF)b),mpfr_roundmode);
        !           186:       break;
        !           187:     default:
        !           188:       goto err;
        !           189:     }
        !           190:
        !           191:     MPFRTOBF(r,d);
        !           192:     *c = (Num)d;
        !           193:   } else
        !           194:     goto err;
        !           195:   if ( !cmpbf(*c,0) ) *c = 0;
        !           196:   return;
        !           197:
        !           198: err: error("subbf : invalid argument");
        !           199: }
        !           200:
        !           201: void mulbf(Num a,Num b,Num *c)
        !           202: {
        !           203:   mpfr_t r;
        !           204:   BF d;
        !           205:   int prec;
        !           206:
        !           207:   if ( !a || !b )
        !           208:     *c = 0;
        !           209:   else if ( (NID(a) <= N_R) && (NID(b) <= N_R ) )
        !           210:     (*mulnumt[MAX(NID(a),NID(b))])(a,b,c);
        !           211:   else if ( NID(a) == N_B ) {
        !           212:     switch ( NID(b) ) {
        !           213:     case N_Q:
        !           214:       mpfr_init2(r,BFPREC(a));
        !           215:       if ( INT(b) )
        !           216:         mpfr_mul_z(r,BDY((BF)a),BDY((Z)b),mpfr_roundmode);
        !           217:       else
        !           218:         mpfr_mul_q(r,BDY((BF)a),BDY((Q)b),mpfr_roundmode);
        !           219:       break;
        !           220:     case N_R:
        !           221:       /* double precision = 53 */
        !           222:       mpfr_init2(r,MAX(BFPREC(a),53));
        !           223:       mpfr_mul_d(r,BDY((BF)a),BDY((Real)b),mpfr_roundmode);
        !           224:       break;
        !           225:     case N_B:
        !           226:       mpfr_init2(r,MAX(BFPREC(a),BFPREC(b)));
        !           227:       mpfr_mul(r,BDY((BF)a),BDY((BF)b),mpfr_roundmode);
        !           228:       break;
        !           229:     default:
        !           230:       goto err;
        !           231:     }
        !           232:     MPFRTOBF(r,d);
        !           233:     *c = (Num)d;
        !           234:   } else if ( NID(b) == N_B ) {
        !           235:     switch ( NID(a) ) {
        !           236:     case N_Q:
        !           237:       mpfr_init2(r,BFPREC(b));
        !           238:       if ( INT(a) )
        !           239:         mpfr_mul_z(r,BDY((BF)b),BDY((Z)a),mpfr_roundmode);
        !           240:       else
        !           241:         mpfr_mul_q(r,BDY((BF)b),BDY((Q)a),mpfr_roundmode);
        !           242:       break;
        !           243:     case N_R:
        !           244:       /* double precision = 53 */
        !           245:       mpfr_init2(r,MAX(BFPREC(b),53));
        !           246:       mpfr_mul_d(r,BDY((BF)b),BDY((Real)a),mpfr_roundmode);
        !           247:       break;
        !           248:     default:
        !           249:       goto err;
        !           250:     }
        !           251:     MPFRTOBF(r,d);
        !           252:     *c = (Num)d;
        !           253:   } else
        !           254:     goto err;
        !           255:
        !           256:   if ( !cmpbf(*c,0) ) *c = 0;
        !           257:   return;
        !           258:
        !           259: err: error("mulbf : invalid argument");
        !           260: }
        !           261:
        !           262: void divbf(Num a,Num b,Num *c)
        !           263: {
        !           264:   mpfr_t s,r;
        !           265:   BF d;
        !           266:
        !           267:   if ( !b )
        !           268:     error("divbf : division by 0");
        !           269:   else if ( !a )
        !           270:     *c = 0;
        !           271:   else if ( (NID(a) <= N_R) && (NID(b) <= N_R ) )
        !           272:     (*divnumt[MAX(NID(a),NID(b))])(a,b,c);
        !           273:   else if ( NID(a) == N_B ) {
        !           274:     switch ( NID(b) ) {
        !           275:     case N_Q:
        !           276:       mpfr_init2(r,BFPREC(a));
        !           277:       if ( INT(b) )
        !           278:         mpfr_div_z(r,BDY((BF)a),BDY((Z)b),mpfr_roundmode);
        !           279:       else
        !           280:         mpfr_div_q(r,BDY((BF)a),BDY((Q)b),mpfr_roundmode);
        !           281:       break;
        !           282:     case N_R:
        !           283:       /* double precision = 53 */
        !           284:       mpfr_init2(r,MAX(BFPREC(a),53));
        !           285:       mpfr_div_d(r,BDY((BF)a),BDY((Real)b),mpfr_roundmode);
        !           286:       break;
        !           287:     case N_B:
        !           288:       mpfr_init2(r,MAX(BFPREC(a),BFPREC(b)));
        !           289:       mpfr_div(r,BDY((BF)a),BDY((BF)b),mpfr_roundmode);
        !           290:       break;
        !           291:     default:
        !           292:       goto err;
        !           293:     }
        !           294:     MPFRTOBF(r,d);
        !           295:     *c = (Num)d;
        !           296:   } else if ( NID(b)==N_B ) {
        !           297:     switch ( NID(a) ) {
        !           298:     case N_Q:
        !           299:       /* XXX : mpfr_z_div and mpfr_q_div are not implemented */
        !           300:       a = tobf(a,BFPREC(b));
        !           301:       mpfr_init2(r,BFPREC(b));
        !           302:       mpfr_div(r,BDY((BF)a),BDY((BF)b),mpfr_roundmode);
        !           303:       break;
        !           304:     case N_R:
        !           305:       /* double precision = 53 */
        !           306:       mpfr_init2(r,MAX(BFPREC(b),53));
        !           307:       mpfr_d_div(r,BDY((Real)a),BDY((BF)b),mpfr_roundmode);
        !           308:       break;
        !           309:     default:
        !           310:       goto err;
        !           311:     }
        !           312:     MPFRTOBF(r,d);
        !           313:     *c = (Num)d;
        !           314:   } else
        !           315:     goto err;
        !           316:
        !           317:   if ( !cmpbf(*c,0) ) *c = 0;
        !           318:   return;
        !           319:
        !           320: err: error("mulbf : invalid argument");
        !           321: }
        !           322:
        !           323: void pwrbf(Num a,Num b,Num *c)
        !           324: {
        !           325:   int prec;
        !           326:   mpfr_t r;
        !           327:   BF d;
        !           328:
        !           329:   if ( !b )
        !           330:     *c = (Num)ONE;
        !           331:   else if ( !a )
        !           332:     *c = 0;
        !           333:   else if ( (NID(a) <= N_R) && (NID(b) <= N_R ) )
        !           334:     (*pwrnumt[MAX(NID(a),NID(b))])(a,b,c);
        !           335:   else if ( NID(a) == N_B ) {
        !           336:     switch ( NID(b) ) {
        !           337:     case N_Q:
        !           338:       mpfr_init2(r,BFPREC(a));
        !           339:       if ( INT(b) ) {
        !           340:         mpfr_pow_z(r,BDY((BF)a),BDY((Z)b),mpfr_roundmode);
        !           341:       } else {
        !           342:         b = tobf(b,BFPREC(a));
        !           343:         mpfr_pow(r,BDY((BF)a),BDY((BF)b),mpfr_roundmode);
        !           344:       }
        !           345:       break;
        !           346:     case N_R:
        !           347:       /* double precision = 53 */
        !           348:       prec = MAX(BFPREC(a),53);
        !           349:       mpfr_init2(r,prec);
        !           350:       b = tobf(b,prec);
        !           351:       mpfr_pow(r,BDY((BF)a),BDY((BF)b),mpfr_roundmode);
        !           352:       break;
        !           353:     case N_B:
        !           354:       mpfr_init2(r,MAX(BFPREC(a),BFPREC(b)));
        !           355:       mpfr_pow(r,BDY((BF)a),BDY((BF)b),mpfr_roundmode);
        !           356:       break;
        !           357:     default:
        !           358:       goto err;
        !           359:     }
        !           360:     MPFRTOBF(r,d);
        !           361:     *c = (Num)d;
        !           362:   } else if ( NID(b)==N_B ) {
        !           363:     switch ( NID(a) ) {
        !           364:     case N_Q:
        !           365:       mpfr_init2(r,BFPREC(b));
        !           366:       a = tobf(a,BFPREC(b));
        !           367:       mpfr_pow(r,BDY((BF)a),BDY((BF)b),mpfr_roundmode);
        !           368:       break;
        !           369:     case N_R:
        !           370:       /* double precision = 53 */
        !           371:       prec = MAX(BFPREC(a),53);
        !           372:       mpfr_init2(r,prec);
        !           373:       a = tobf(a,prec);
        !           374:       mpfr_pow(r,BDY((BF)a),BDY((BF)b),mpfr_roundmode);
        !           375:       break;
        !           376:     default:
        !           377:       goto err;
        !           378:     }
        !           379:     MPFRTOBF(r,d);
        !           380:     *c = (Num)d;
        !           381:   } else
        !           382:     goto err;
        !           383:
        !           384:   if ( !cmpbf(*c,0) ) *c = 0;
        !           385:   return;
        !           386:
        !           387: err: error("pwrbf : invalid argument");
        !           388: }
        !           389:
        !           390: void chsgnbf(Num a,Num *c)
        !           391: {
        !           392:   mpfr_t r;
        !           393:   BF d;
        !           394:
        !           395:   if ( !a )
        !           396:     *c = 0;
        !           397:   else if ( NID(a) <= N_R )
        !           398:     (*chsgnnumt[NID(a)])(a,c);
        !           399:   else if ( NID(a) == N_B ) {
        !           400:     mpfr_init2(r,BFPREC(a));
        !           401:     mpfr_neg(r,BDY((BF)a),mpfr_roundmode);
        !           402:     MPFRTOBF(r,d);
        !           403:     *c = (Num)d;
        !           404:   } else
        !           405:     error("chsgnbf : invalid argument");
        !           406: }
        !           407:
        !           408: int cmpbf(Num a,Num b)
        !           409: {
        !           410:   int ret;
        !           411:
        !           412:   if ( !a ) {
        !           413:     if ( !b ) return 0;
        !           414:     else if ( NID(b)<=N_R )
        !           415:       return (*cmpnumt[NID(b)])(a,b);
        !           416:     else if ( NID(b)==N_B )
        !           417:       return -mpfr_sgn(BDY((BF)b));
        !           418:     else
        !           419:       goto err;
        !           420:   } else if ( !b ) {
        !           421:     if ( NID(a)<=N_R )
        !           422:       return (*cmpnumt[NID(a)])(a,b);
        !           423:     else if ( NID(a)==N_B )
        !           424:       return mpfr_sgn(BDY((BF)a));
        !           425:     else
        !           426:       goto err;
        !           427:   } else if ( NID(a) <= N_R && NID(b) <= N_R )
        !           428:     return (*cmpnumt[MAX(NID(a),NID(b))])(a,b);
        !           429:   else if ( NID(a) == N_B ) {
        !           430:     switch ( NID(b) ) {
        !           431:     case N_Q:
        !           432:       if ( INT(b) )
        !           433:         ret = mpfr_cmp_z(BDY((BF)a),BDY((Z)b));
        !           434:       else
        !           435:         ret = mpfr_cmp_q(BDY((BF)a),BDY((Q)b));
        !           436:       break;
        !           437:     case N_R:
        !           438:       /* double precision = 53 */
        !           439:       ret = mpfr_cmp_d(BDY((BF)a),BDY((Real)b));
        !           440:       break;
        !           441:     case N_B:
        !           442:       ret = mpfr_cmp(BDY((BF)a),BDY((BF)b));
        !           443:       break;
        !           444:     default:
        !           445:       goto err;
        !           446:     }
        !           447:     return ret;
        !           448:   } else if ( NID(b)==N_B ) {
        !           449:     switch ( NID(a) ) {
        !           450:     case N_Q:
        !           451:       if ( INT(a) )
        !           452:         ret = mpfr_cmp_z(BDY((BF)b),BDY((Z)a));
        !           453:       else
        !           454:         ret = mpfr_cmp_q(BDY((BF)b),BDY((Q)a));
        !           455:       break;
        !           456:     case N_R:
        !           457:       /* double precision = 53 */
        !           458:       ret = mpfr_cmp_d(BDY((BF)b),BDY((Real)a));
        !           459:       break;
        !           460:     default:
        !           461:       goto err;
        !           462:     }
        !           463:     return -ret;
        !           464:   }
        !           465: err: error("cmpbf : cannot compare");
        !           466:   return 0;
        !           467: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>