[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.56 and 1.57

version 1.56, 2017/11/29 19:13:31 version 1.57, 2017/12/01 19:04:15
Line 354 
Line 354 
   
         abs_scale = s > 0 ? s : -s;          abs_scale = s > 0 ? s : -s;
   
         if (abs_scale < sizeof(factors)/sizeof(factors[0])) {          if (abs_scale < nitems(factors)) {
                 if (s > 0)                  if (s > 0)
                         bn_check(BN_mul_word(n, factors[abs_scale]));                          bn_check(BN_mul_word(n, factors[abs_scale]));
                 else                  else
Line 390 
Line 390 
   
         bn_checkp(BN_copy(i, n->number));          bn_checkp(BN_copy(i, n->number));
   
         if (n->scale == 0 && f != NULL)          if (n->scale == 0) {
                 bn_check(BN_set_word(f, 0));                  if (f != NULL)
         else if (n->scale < sizeof(factors)/sizeof(factors[0])) {                          bn_check(BN_set_word(f, 0));
           } else if (n->scale < nitems(factors)) {
                 rem = BN_div_word(i, factors[n->scale]);                  rem = BN_div_word(i, factors[n->scale]);
                 if (f != NULL)                  if (f != NULL)
                         bn_check(BN_set_word(f, rem));                          bn_check(BN_set_word(f, rem));
Line 697 
Line 698 
 static u_int  static u_int
 count_digits(const struct number *n)  count_digits(const struct number *n)
 {  {
         struct number   *int_part, *fract_part;          BIGNUM          *int_part, *a, *p;
         u_int           i;          BN_CTX          *ctx;
           uint            d;
           const uint64_t  c = 1292913986; /* floor(2^32 * log_10(2)) */
           int             bits;
   
         if (BN_is_zero(n->number))          if (BN_is_zero(n->number))
                 return n->scale ? n->scale : 1;                  return n->scale ? n->scale : 1;
   
         int_part = new_number();          int_part = BN_new();
         fract_part = new_number();          bn_checkp(int_part);
         fract_part->scale = n->scale;  
         split_number(n, int_part->number, fract_part->number);  
   
         i = 0;          split_number(n, int_part, NULL);
         while (!BN_is_zero(int_part->number)) {          bits = BN_num_bits(int_part);
                 (void)BN_div_word(int_part->number, 10);  
                 i++;          if (bits == 0)
                   d = 0;
           else {
                   /*
                    * Estimate number of decimal digits based on number of bits.
                    * Divide 2^32 factor out by shifting
                    */
                   d = (c * bits) >> 32;
   
                   /* If close to a possible rounding error fix if needed */
                   if (d != (c * (bits - 1)) >> 32) {
                           ctx = BN_CTX_new();
                           bn_checkp(ctx);
                           a = BN_new();
                           bn_checkp(a);
                           p = BN_new();
                           bn_checkp(p);
   
                           bn_check(BN_set_word(a, 10));
                           bn_check(BN_set_word(p, d));
                           bn_check(BN_exp(a, a, p, ctx));
   
                           if (BN_ucmp(int_part, a) >= 0)
                                   d++;
   
                           BN_CTX_free(ctx);
                           BN_free(a);
                           BN_free(p);
                   } else
                           d++;
         }          }
         free_number(int_part);  
         free_number(fract_part);          BN_free(int_part);
         return i + n->scale;  
           return d + n->scale;
 }  }
   
 static void  static void

Legend:
Removed from v.1.56  
changed lines
  Added in v.1.57