[BACK]Return to bcode.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / dc

Diff for /src/usr.bin/dc/bcode.c between version 1.44 and 1.45

version 1.44, 2012/11/06 16:00:05 version 1.45, 2012/11/07 11:06:14
Line 257 
Line 257 
         (void)signal(SIGINT, sighandler);          (void)signal(SIGINT, sighandler);
 }  }
   
   u_int
   bmachine_scale(void)
   {
           return bmachine.scale;
   }
   
 /* Reset the things needed before processing a (new) file */  /* Reset the things needed before processing a (new) file */
 void  void
 reset_bmachine(struct source *src)  reset_bmachine(struct source *src)
Line 991 
Line 997 
 }  }
   
 void  void
 bmul_number(struct number *r, struct number *a, struct number *b)  bmul_number(struct number *r, struct number *a, struct number *b, u_int scale)
 {  {
         BN_CTX          *ctx;          BN_CTX          *ctx;
   
Line 1005 
Line 1011 
         bn_check(BN_mul(r->number, a->number, b->number, ctx));          bn_check(BN_mul(r->number, a->number, b->number, ctx));
         BN_CTX_free(ctx);          BN_CTX_free(ctx);
   
         if (rscale > bmachine.scale && rscale > ascale && rscale > bscale) {          r->scale = rscale;
                 r->scale = rscale;          if (rscale > bmachine.scale && rscale > ascale && rscale > bscale)
                 normalize(r, max(bmachine.scale, max(ascale, bscale)));                  normalize(r, max(scale, max(ascale, bscale)));
         } else  
                 r->scale = rscale;  
 }  }
   
 static void  static void
Line 1029 
Line 1033 
         }          }
   
         r = new_number();          r = new_number();
         bmul_number(r, a, b);          bmul_number(r, a, b, bmachine.scale);
   
         push_number(r);          push_number(r);
         free_number(a);          free_number(a);
Line 1160 
Line 1164 
         struct number   *a, *p;          struct number   *a, *p;
         struct number   *r;          struct number   *r;
         bool            neg;          bool            neg;
         u_int           scale;          u_int           rscale;
   
         p = pop_number();          p = pop_number();
         if (p == NULL) {          if (p == NULL) {
Line 1191 
Line 1195 
         if (BN_is_negative(p->number)) {          if (BN_is_negative(p->number)) {
                 neg = true;                  neg = true;
                 negate(p);                  negate(p);
                 scale = bmachine.scale;                  rscale = bmachine.scale;
         } else {          } else {
                 /* Posix bc says min(a.scale * b, max(a.scale, scale) */                  /* Posix bc says min(a.scale * b, max(a.scale, scale) */
                 u_long  b;                  u_long  b;
Line 1199 
Line 1203 
   
                 b = BN_get_word(p->number);                  b = BN_get_word(p->number);
                 m = max(a->scale, bmachine.scale);                  m = max(a->scale, bmachine.scale);
                 scale = a->scale * (u_int)b;                  rscale = a->scale * (u_int)b;
                 if (scale > m || (a->scale > 0 && (b == BN_MASK2 ||                  if (rscale > m || (a->scale > 0 && (b == BN_MASK2 ||
                     b > UINT_MAX)))                      b > UINT_MAX)))
                         scale = m;                          rscale = m;
         }          }
   
         if (BN_is_zero(p->number)) {          if (BN_is_zero(p->number)) {
                 r = new_number();                  r = new_number();
                 bn_check(BN_one(r->number));                  bn_check(BN_one(r->number));
                 normalize(r, scale);                  normalize(r, rscale);
         } else {          } else {
                   u_int ascale, mscale;
   
                   ascale = a->scale;
                 while (!BN_is_bit_set(p->number, 0)) {                  while (!BN_is_bit_set(p->number, 0)) {
                         bmul_number(a, a, a);                          ascale *= 2;
                           bmul_number(a, a, a, ascale);
                         bn_check(BN_rshift1(p->number, p->number));                          bn_check(BN_rshift1(p->number, p->number));
                 }                  }
   
                 r = dup_number(a);                  r = dup_number(a);
                 normalize(r, scale);  
                 bn_check(BN_rshift1(p->number, p->number));                  bn_check(BN_rshift1(p->number, p->number));
   
                   mscale = ascale;
                 while (!BN_is_zero(p->number)) {                  while (!BN_is_zero(p->number)) {
                         bmul_number(a, a, a);                          ascale *= 2;
                         if (BN_is_bit_set(p->number, 0))                          bmul_number(a, a, a, ascale);
                                 bmul_number(r, r, a);                          if (BN_is_bit_set(p->number, 0)) {
                                   mscale += ascale;
                                   bmul_number(r, r, a, mscale);
                           }
                         bn_check(BN_rshift1(p->number, p->number));                          bn_check(BN_rshift1(p->number, p->number));
                 }                  }
   
Line 1235 
Line 1246 
                         bn_check(BN_one(one));                          bn_check(BN_one(one));
                         ctx = BN_CTX_new();                          ctx = BN_CTX_new();
                         bn_checkp(ctx);                          bn_checkp(ctx);
                         scale_number(one, r->scale + scale);                          scale_number(one, r->scale + rscale);
                         normalize(r, scale);  
   
                         if (BN_is_zero(r->number))                          if (BN_is_zero(r->number))
                                 warnx("divide by zero");                                  warnx("divide by zero");
Line 1245 
Line 1255 
                                     r->number, ctx));                                      r->number, ctx));
                         BN_free(one);                          BN_free(one);
                         BN_CTX_free(ctx);                          BN_CTX_free(ctx);
                           r->scale = rscale;
                 } else                  } else
                         normalize(r, scale);                          normalize(r, rscale);
         }          }
         push_number(r);          push_number(r);
         free_number(a);          free_number(a);

Legend:
Removed from v.1.44  
changed lines
  Added in v.1.45