Oops,

I forgot to sort out the catastrophic loss of precision on differences.  So that
means that on add and subtract we need to use the maximum fabs value
of the operands to calculate the rounding trather than the result itself:

So redecimalize() becomes:

double redecimalize(double dval,double rval)
{
    double f;
    if (dval == 0)
   {
      return dval;
   }
   f = pow(10.0, (double) DBL_DIG - (1 + floor(log10(fabs(rval)))));
   return (double) (rint(dval*f))/f;
  }


and add_function, div_function need to look more like:

double dop1,dop2,rval;
....
 if ((op1->type == IS_DOUBLE || op1->type == IS_LONG)
  && (op2->type == IS_LONG || op2->type == IS_DOUBLE)) {
  dop1 = (op1->type == IS_LONG) ? ((double) op1->value.lval):op1->value.dval;
  dop2 = (op2->type == IS_LONG) ? ((double) op2->value.lval):op2->value.dval;
  result->value.dval = dop1 - dop2;
  rval = fabs(dop1) > fabs(dop2) ? dop1:dop2;
  result->value.dval = redecimalize(result->value.dval,rval);
  result->type = IS_DOUBLE;
  return SUCCESS;
 }

The calls to redecimalize on mul_function,div_function simply pass the
result twice e.g.
   result->value.dval = redecimalize(result->value.dval,result->value.dval);

There's no significant impact on performance.

George




-- 
PHP Development Mailing List <http://www.php.net/>
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to