--- math.c_fixed Wed Jul 21 15:32:27 2004 +++ math.c_original Tue Jul 20 18:57:39 2004 @@ -51,284 +51,7 @@ } \ tmp_val /= f; \ val = !zend_isnan(tmp_val) ? tmp_val : val; \ -} -\ - -#define INTELGNU 1 - -#ifdef INTELGNU -#include -#endif - -double getintpow10(int power) { -/* fast pow() for integer powers of ten <= 1e22 i.e. exact powers of ten */ -static double powers[23] = {1e0,1e1,1e2,1e3,1e4,1e5,1e6,1e7,1e8,1e9,1e10,1e11,1e12,1e13,1e14,1e15,1e16,1e17,1e18,1e19,1e20,1e21,1e22}; - -if (power > 22 || power < 0) -{ - return pow(10.0, (double) power); -} else { - return powers[power]; -} - -} - - -int getintlog10(double val) { -/* fast floor(log10(fabs(val))) */ -int ret_val; -val = fabs(val); -if (val < 1e-8 || val > 1e23) -{ - ret_val = (int) floor(log10(val)); -} else { - if (val < 1e8) { - if (val < 1e0) { - if (val < 1e-4) { - if (val < 1e-6) { - if (val < 1e-7) { - ret_val = -8; - } else { - ret_val = -7; - } - } else { - if (val < 1e-5) { - ret_val = -6; - } else { - ret_val = -5; - } - } - } else { - if (val < 1e-2) { - if (val < 1e-3) { - ret_val = -4; - } else { - ret_val = -3; - } - } else { - if (val < 1e-1) { - ret_val = -2; - } else { - ret_val = -1; - } - } - } - } else { - if (val < 1e4) { - if (val < 1e2) { - if (val < 1e1) { - ret_val = 0; - } else { - ret_val = 1; - } - } else { - if (val < 1e3) { - ret_val = 2; - } else { - ret_val = 3; - } - } - } else { - if (val < 1e6) { - if (val < 1e5) { - ret_val = 4; - } else { - ret_val = 5; - } - } else { - if (val < 1e7) { - ret_val = 6; - } else { - ret_val = 7; - } - } - } - } - } else { - if (val < 1e16) { - if (val < 1e12) { - if (val < 1e10) { - if (val < 1e9) { - ret_val = 8; - } else { - ret_val = 9; - } - } else { - if (val < 1e11) { - ret_val = 10; - } else { - ret_val = 11; - } - } - } else { - if (val < 1e14) { - if (val < 1e13) { - ret_val = 12; - } else { - ret_val = 13; - } - } else { - if (val < 1e15) { - ret_val = 14; - } else { - ret_val = 15; - } - } - } - } else { - if (val < 1e20) { - if (val < 1e18) { - if (val < 1e17) { - ret_val = 16; - } else { - ret_val = 17; - } - } else { - if (val < 1e19 ){ - ret_val = 18; - } else { - ret_val = 19; - } - } - } else { - if (val < 1e22) { - if (val < 1e21) { - ret_val = 20; - } else { - ret_val = 21; - } - } else { - ret_val = 22; - } - } - } - } -} -return ret_val; -} - - - - -double round_central(double val,int places TSRMLS_DC) -{ -/* -function to replace PHP_ROUND_WITH_FUZZ macro -1. switches IntelGNU FPUs to double-precision from default of extended precision - and back again at the end to eliminate extended precision bugs -2. for rounding to more than (+/-) 22 places i.e. inexact power of ten, uses -platforms own strtod() to evaluate final result -3. handles round half even as well as round half up (default) -4. uses getintpow10 to improve on pow() performance for exact powers of ten -*/ - -double tmp_val; -double tmp_val2; -double f; -char buff[60]; -int round_half_even; - -#ifdef INTELGNU -fpu_control_t cw = 0x027f,store_cw; - _FPU_GETCW(store_cw); - _FPU_SETCW(cw); -#endif - -/* -uncomment following line and remove succeeding line when round_half_even -configuration working -round_half_even = (EG(rounding_mode) == ROUND_HALF_EVEN); -*/ -round_half_even = 0; - -f=getintpow10(abs(places)); -if (places>0) -{ - tmp_val2 = val * f; -} else { - tmp_val2 = val / f; -} - -/* Check for out of ranges first */ - -if (fabs(tmp_val2) >= 1e15) -{ - tmp_val = val; -} else { - if (val >= 0.0) { - tmp_val = floor(tmp_val2 + 0.5); - if(round_half_even && tmp_val2 == (0.5 + 2 * floor(tmp_val/2))) - { - tmp_val = tmp_val - 1; - } - } else { - tmp_val = ceil(tmp_val2 - 0.5); - if(round_half_even && tmp_val2 == (-0.5 + 2 * ceil(tmp_val/2))) - { - tmp_val = tmp_val + 1; - } - } - - if (abs(places)<23) - { - if (places>0) - { - tmp_val = tmp_val / f; - } else { - tmp_val = tmp_val * f; - } - } else { - sprintf(buff,"%15fe%d",tmp_val,0-places); - tmp_val = strtod(buff,NULL); - } -} -#ifdef INTELGNU -/* reset fpu to original, stored value */ - _FPU_SETCW(store_cw); -#endif -tmp_val = !zend_isnan(tmp_val) ? tmp_val : val; - -return tmp_val; -} - - -double round_to_precision(double val1, double val2, double val3 TSRMLS_DC) { -/* -wrapper to round_central (qv) for arithmetic functions -- calculates places for round_central based on 15 digits of passed value - - for addition/subtraction val2 and val3 should be set to original operands to prevent - catastrophic loss of precision on differences - - for multiplication/division, val2 and val3 should be zero. -*/ - -double tmp_val; -int places; -if (fabs(val1) > fabs(val2)) -{ - if (fabs(val1)>fabs(val3)) - { - tmp_val = fabs(val1); - } else { - if (fabs(val2) > fabs(val3)) - { - tmp_val = fabs(val2); - } else { - tmp_val = fabs(val3); - } - } -} else { - if (fabs(val2) > fabs(val3)) - { - tmp_val = fabs(val2); - } else { - tmp_val = fabs(val3); - } -} -places = 14 - getintlog10(tmp_val); -return round_central(val1,places TSRMLS_DC); - -} - +} \ /* {{{ proto int abs(int number) Return the absolute value of the number */ @@ -437,9 +160,7 @@ return_val = (Z_TYPE_PP(value) == IS_LONG) ? (double)Z_LVAL_PP(value) : Z_DVAL_PP(value); -/* PHP_ROUND_WITH_FUZZ(return_val, places); */ - - return_val = round_central(return_val, places TSRMLS_DC); + PHP_ROUND_WITH_FUZZ(return_val, places); RETURN_DOUBLE(return_val); break; @@ -1301,9 +1022,8 @@ dec = MAX(0, dec); } -/* PHP_ROUND_WITH_FUZZ(d, dec); */ - d=round_central(d, dec); - + PHP_ROUND_WITH_FUZZ(d, dec); + tmplen = spprintf(&tmpbuf, 0, "%.*f", dec, d); if (tmpbuf == NULL || !isdigit((int)tmpbuf[0])) { --- formatted_print.c_fixed Tue Jul 20 19:49:05 2004 +++ formatted_print.c_original Tue Jul 20 19:00:37 2004 @@ -50,7 +50,6 @@ static char hexchars[] = "0123456789abcdef"; static char HEXCHARS[] = "0123456789ABCDEF"; -double round_central(double,int TSRMLS_DC); /* * cvt.c - IEEE floating point formatting routines for FreeBSD @@ -327,11 +326,7 @@ alignment, precision, sign, 0, always_sign); return; } -/* if (EG(exact_decimal_arithmetic) && fmt != 'e')) */ - if (fmt != 'e') - { - number = round_central(number,precision TSRMLS_DC); - } + cvt = php_convert_to_decimal(number, precision, &decpt, &sign, (fmt == 'e')); cvt_len = strlen(cvt); --- zend_operators.c_fixed Tue Jul 20 19:48:33 2004 +++ zend_operators.c_original Tue Jul 20 18:34:23 2004 @@ -32,12 +32,6 @@ #define LONG_SIGN_MASK (1L << (8*sizeof(long)-1)) - - -double round_to_precision(double,double,double TSRMLS_DC); -double round_central(double,int TSRMLS_DC); -int getintlog10(double); - ZEND_API int zend_atoi(const char *str, int str_len) { int retval; @@ -548,8 +542,6 @@ case IS_DOUBLE: { TSRMLS_FETCH(); dval = op->value.dval; -/* if (EG(exact_decimal_arithmetic)) */ - dval = round_central(dval,(((int) EG(precision))-(1+getintlog10(dval))) TSRMLS_DC); op->value.str.val = (char *) emalloc_rel(MAX_LENGTH_OF_DOUBLE + EG(precision) + 1); op->value.str.len = zend_sprintf(op->value.str.val, "%.*G", (int) EG(precision), dval); /* SAFE */ /* %G already handles removing trailing zeros from the fractional part, yay */ @@ -774,16 +766,11 @@ (((double) op1->value.lval) + op2->value.dval) : (op1->value.dval + ((double) op2->value.lval))); result->type = IS_DOUBLE; -/* if (EG(exact_decimal_arithmetic)) */ - result->value.dval = round_to_precision(result->value.dval,op1->type == IS_LONG ?((double)op1->value.lval):op1->value.dval,op2->type == IS_LONG?((double)op2->value.lval):op2->value.dval TSRMLS_DC); - return SUCCESS; } if (op1->type == IS_DOUBLE && op2->type == IS_DOUBLE) { result->type = IS_DOUBLE; result->value.dval = op1->value.dval + op2->value.dval; -/* if (EG(exact_decimal_arithmetic)) */ - result->value.dval = round_to_precision(result->value.dval,op1->value.dval,op2->value.dval TSRMLS_DC); return SUCCESS; } zend_error(E_ERROR, "Unsupported operand types"); @@ -819,16 +806,11 @@ (((double) op1->value.lval) - op2->value.dval) : (op1->value.dval - ((double) op2->value.lval))); result->type = IS_DOUBLE; -/* if (EG(exact_decimal_arithmetic)) */ - result->value.dval = round_to_precision(result->value.dval,op1->type == IS_LONG ?((double)op1->value.lval):op1->value.dval,op2->type == IS_LONG?((double)op2->value.lval):op2->value.dval TSRMLS_DC); - return SUCCESS; } if (op1->type == IS_DOUBLE && op2->type == IS_DOUBLE) { result->type = IS_DOUBLE; result->value.dval = op1->value.dval - op2->value.dval; -/* if (EG(exact_decimal_arithmetic)) */ - result->value.dval = round_to_precision(result->value.dval,op1->value.dval,op2->value.dval TSRMLS_DC); return SUCCESS; } zend_error(E_ERROR, "Unsupported operand types"); @@ -856,15 +838,11 @@ (((double) op1->value.lval) * op2->value.dval) : (op1->value.dval * ((double) op2->value.lval))); result->type = IS_DOUBLE; -/* if (EG(exact_decimal_arithmetic)) */ - result->value.dval = round_to_precision(result->value.dval,0,0 TSRMLS_DC); return SUCCESS; } if (op1->type == IS_DOUBLE && op2->type == IS_DOUBLE) { result->type = IS_DOUBLE; result->value.dval = op1->value.dval * op2->value.dval; -/* if (EG(exact_decimal_arithmetic)) */ - result->value.dval = round_to_precision(result->value.dval,0,0 TSRMLS_DC); return SUCCESS; } zend_error(E_ERROR, "Unsupported operand types"); @@ -899,15 +877,11 @@ (((double) op1->value.lval) / op2->value.dval) : (op1->value.dval / ((double) op2->value.lval))); result->type = IS_DOUBLE; -/* if (EG(exact_decimal_arithmetic)) */ - result->value.dval = round_to_precision(result->value.dval,0,0 TSRMLS_DC); return SUCCESS; } if (op1->type == IS_DOUBLE && op2->type == IS_DOUBLE) { result->type = IS_DOUBLE; result->value.dval = op1->value.dval / op2->value.dval; -/* if (EG(exact_decimal_arithmetic)) */ - result->value.dval = round_to_precision(result->value.dval,0,0 TSRMLS_DC); return SUCCESS; } zend_error(E_ERROR, "Unsupported operand types"); @@ -1965,8 +1939,6 @@ double dval = op->value.dval; TSRMLS_FETCH(); -/* if (EG(exact_decimal_arithmetic)) */ - dval = round_central(dval,(((int) EG(precision))-(1+getintlog10(dval))) TSRMLS_DC); op->value.str.val = (char *) emalloc_rel(MAX_LENGTH_OF_DOUBLE + EG(precision) + 1); sprintf(op->value.str.val, "%.*G", (int) EG(precision), dval);