mirror of
https://github.com/php/php-src.git
synced 2025-08-16 05:58:45 +02:00
Fixed floating point mathematic speed degradation (Christian)
This commit is contained in:
parent
d3b42700a0
commit
31c0af245e
11 changed files with 93 additions and 65 deletions
|
@ -30,7 +30,6 @@
|
|||
#include "zend_multiply.h"
|
||||
#include "zend_strtod.h"
|
||||
#include "zend_exceptions.h"
|
||||
#include "zend_float.h"
|
||||
|
||||
#define LONG_SIGN_MASK (1L << (8*sizeof(long)-1))
|
||||
|
||||
|
@ -742,7 +741,6 @@ ZEND_API void multi_convert_to_string_ex(int argc, ...)
|
|||
|
||||
ZEND_API int add_function(zval *result, zval *op1, zval *op2 TSRMLS_DC)
|
||||
{
|
||||
ZEND_FLOAT_DECLARE
|
||||
zval op1_copy, op2_copy;
|
||||
int converted = 0;
|
||||
|
||||
|
@ -755,9 +753,7 @@ ZEND_API int add_function(zval *result, zval *op1, zval *op2 TSRMLS_DC)
|
|||
if ((Z_LVAL_P(op1) & LONG_SIGN_MASK) == (Z_LVAL_P(op2) & LONG_SIGN_MASK)
|
||||
&& (Z_LVAL_P(op1) & LONG_SIGN_MASK) != (lval & LONG_SIGN_MASK)) {
|
||||
|
||||
ZEND_FLOAT_ENSURE();
|
||||
ZVAL_DOUBLE(result, (double) Z_LVAL_P(op1) + (double) Z_LVAL_P(op2));
|
||||
ZEND_FLOAT_RESTORE();
|
||||
} else {
|
||||
ZVAL_LONG(result, lval);
|
||||
}
|
||||
|
@ -765,21 +761,15 @@ ZEND_API int add_function(zval *result, zval *op1, zval *op2 TSRMLS_DC)
|
|||
}
|
||||
|
||||
case TYPE_PAIR(IS_LONG, IS_DOUBLE):
|
||||
ZEND_FLOAT_ENSURE();
|
||||
ZVAL_DOUBLE(result, ((double)Z_LVAL_P(op1)) + Z_DVAL_P(op2));
|
||||
ZEND_FLOAT_RESTORE();
|
||||
return SUCCESS;
|
||||
|
||||
case TYPE_PAIR(IS_DOUBLE, IS_LONG):
|
||||
ZEND_FLOAT_ENSURE();
|
||||
ZVAL_DOUBLE(result, Z_DVAL_P(op1) + ((double)Z_LVAL_P(op2)));
|
||||
ZEND_FLOAT_RESTORE();
|
||||
return SUCCESS;
|
||||
|
||||
case TYPE_PAIR(IS_DOUBLE, IS_DOUBLE):
|
||||
ZEND_FLOAT_ENSURE();
|
||||
ZVAL_DOUBLE(result, Z_DVAL_P(op1) + Z_DVAL_P(op2));
|
||||
ZEND_FLOAT_RESTORE();
|
||||
return SUCCESS;
|
||||
|
||||
case TYPE_PAIR(IS_ARRAY, IS_ARRAY): {
|
||||
|
@ -813,7 +803,6 @@ ZEND_API int add_function(zval *result, zval *op1, zval *op2 TSRMLS_DC)
|
|||
|
||||
ZEND_API int sub_function(zval *result, zval *op1, zval *op2 TSRMLS_DC)
|
||||
{
|
||||
ZEND_FLOAT_DECLARE
|
||||
zval op1_copy, op2_copy;
|
||||
int converted = 0;
|
||||
|
||||
|
@ -826,9 +815,7 @@ ZEND_API int sub_function(zval *result, zval *op1, zval *op2 TSRMLS_DC)
|
|||
if ((Z_LVAL_P(op1) & LONG_SIGN_MASK) != (Z_LVAL_P(op2) & LONG_SIGN_MASK)
|
||||
&& (Z_LVAL_P(op1) & LONG_SIGN_MASK) != (lval & LONG_SIGN_MASK)) {
|
||||
|
||||
ZEND_FLOAT_ENSURE();
|
||||
ZVAL_DOUBLE(result, (double) Z_LVAL_P(op1) - (double) Z_LVAL_P(op2));
|
||||
ZEND_FLOAT_RESTORE();
|
||||
} else {
|
||||
ZVAL_LONG(result, lval);
|
||||
}
|
||||
|
@ -836,21 +823,15 @@ ZEND_API int sub_function(zval *result, zval *op1, zval *op2 TSRMLS_DC)
|
|||
|
||||
}
|
||||
case TYPE_PAIR(IS_LONG, IS_DOUBLE):
|
||||
ZEND_FLOAT_ENSURE();
|
||||
ZVAL_DOUBLE(result, ((double)Z_LVAL_P(op1)) - Z_DVAL_P(op2));
|
||||
ZEND_FLOAT_RESTORE();
|
||||
return SUCCESS;
|
||||
|
||||
case TYPE_PAIR(IS_DOUBLE, IS_LONG):
|
||||
ZEND_FLOAT_ENSURE();
|
||||
ZVAL_DOUBLE(result, Z_DVAL_P(op1) - ((double)Z_LVAL_P(op2)));
|
||||
ZEND_FLOAT_RESTORE();
|
||||
return SUCCESS;
|
||||
|
||||
case TYPE_PAIR(IS_DOUBLE, IS_DOUBLE):
|
||||
ZEND_FLOAT_ENSURE();
|
||||
ZVAL_DOUBLE(result, Z_DVAL_P(op1) - Z_DVAL_P(op2));
|
||||
ZEND_FLOAT_RESTORE();
|
||||
return SUCCESS;
|
||||
|
||||
default:
|
||||
|
@ -869,7 +850,6 @@ ZEND_API int sub_function(zval *result, zval *op1, zval *op2 TSRMLS_DC)
|
|||
|
||||
ZEND_API int mul_function(zval *result, zval *op1, zval *op2 TSRMLS_DC)
|
||||
{
|
||||
ZEND_FLOAT_DECLARE
|
||||
zval op1_copy, op2_copy;
|
||||
int converted = 0;
|
||||
|
||||
|
@ -878,29 +858,21 @@ ZEND_API int mul_function(zval *result, zval *op1, zval *op2 TSRMLS_DC)
|
|||
case TYPE_PAIR(IS_LONG, IS_LONG): {
|
||||
long overflow;
|
||||
|
||||
ZEND_FLOAT_ENSURE();
|
||||
ZEND_SIGNED_MULTIPLY_LONG(Z_LVAL_P(op1),Z_LVAL_P(op2), Z_LVAL_P(result),Z_DVAL_P(result),overflow);
|
||||
ZEND_FLOAT_RESTORE();
|
||||
Z_TYPE_P(result) = overflow ? IS_DOUBLE : IS_LONG;
|
||||
return SUCCESS;
|
||||
|
||||
}
|
||||
case TYPE_PAIR(IS_LONG, IS_DOUBLE):
|
||||
ZEND_FLOAT_ENSURE();
|
||||
ZVAL_DOUBLE(result, ((double)Z_LVAL_P(op1)) * Z_DVAL_P(op2));
|
||||
ZEND_FLOAT_RESTORE();
|
||||
return SUCCESS;
|
||||
|
||||
case TYPE_PAIR(IS_DOUBLE, IS_LONG):
|
||||
ZEND_FLOAT_ENSURE();
|
||||
ZVAL_DOUBLE(result, Z_DVAL_P(op1) * ((double)Z_LVAL_P(op2)));
|
||||
ZEND_FLOAT_RESTORE();
|
||||
return SUCCESS;
|
||||
|
||||
case TYPE_PAIR(IS_DOUBLE, IS_DOUBLE):
|
||||
ZEND_FLOAT_ENSURE();
|
||||
ZVAL_DOUBLE(result, Z_DVAL_P(op1) * Z_DVAL_P(op2));
|
||||
ZEND_FLOAT_RESTORE();
|
||||
return SUCCESS;
|
||||
|
||||
default:
|
||||
|
@ -918,7 +890,6 @@ ZEND_API int mul_function(zval *result, zval *op1, zval *op2 TSRMLS_DC)
|
|||
|
||||
ZEND_API int div_function(zval *result, zval *op1, zval *op2 TSRMLS_DC)
|
||||
{
|
||||
ZEND_FLOAT_DECLARE
|
||||
zval op1_copy, op2_copy;
|
||||
int converted = 0;
|
||||
|
||||
|
@ -931,17 +902,13 @@ ZEND_API int div_function(zval *result, zval *op1, zval *op2 TSRMLS_DC)
|
|||
return FAILURE; /* division by zero */
|
||||
} else if (Z_LVAL_P(op2) == -1 && Z_LVAL_P(op1) == LONG_MIN) {
|
||||
/* Prevent overflow error/crash */
|
||||
ZEND_FLOAT_ENSURE();
|
||||
ZVAL_DOUBLE(result, (double) LONG_MIN / -1);
|
||||
ZEND_FLOAT_RESTORE();
|
||||
return SUCCESS;
|
||||
}
|
||||
if (Z_LVAL_P(op1) % Z_LVAL_P(op2) == 0) { /* integer */
|
||||
ZVAL_LONG(result, Z_LVAL_P(op1) / Z_LVAL_P(op2));
|
||||
} else {
|
||||
ZEND_FLOAT_ENSURE();
|
||||
ZVAL_DOUBLE(result, ((double) Z_LVAL_P(op1)) / Z_LVAL_P(op2));
|
||||
ZEND_FLOAT_RESTORE();
|
||||
}
|
||||
return SUCCESS;
|
||||
|
||||
|
@ -951,9 +918,7 @@ ZEND_API int div_function(zval *result, zval *op1, zval *op2 TSRMLS_DC)
|
|||
ZVAL_BOOL(result, 0);
|
||||
return FAILURE; /* division by zero */
|
||||
}
|
||||
ZEND_FLOAT_ENSURE();
|
||||
ZVAL_DOUBLE(result, Z_DVAL_P(op1) / (double)Z_LVAL_P(op2));
|
||||
ZEND_FLOAT_RESTORE();
|
||||
return SUCCESS;
|
||||
|
||||
case TYPE_PAIR(IS_LONG, IS_DOUBLE):
|
||||
|
@ -962,9 +927,7 @@ ZEND_API int div_function(zval *result, zval *op1, zval *op2 TSRMLS_DC)
|
|||
ZVAL_BOOL(result, 0);
|
||||
return FAILURE; /* division by zero */
|
||||
}
|
||||
ZEND_FLOAT_ENSURE();
|
||||
ZVAL_DOUBLE(result, (double)Z_LVAL_P(op1) / Z_DVAL_P(op2));
|
||||
ZEND_FLOAT_RESTORE();
|
||||
return SUCCESS;
|
||||
|
||||
case TYPE_PAIR(IS_DOUBLE, IS_DOUBLE):
|
||||
|
@ -973,9 +936,7 @@ ZEND_API int div_function(zval *result, zval *op1, zval *op2 TSRMLS_DC)
|
|||
ZVAL_BOOL(result, 0);
|
||||
return FAILURE; /* division by zero */
|
||||
}
|
||||
ZEND_FLOAT_ENSURE();
|
||||
ZVAL_DOUBLE(result, Z_DVAL_P(op1) / Z_DVAL_P(op2));
|
||||
ZEND_FLOAT_RESTORE();
|
||||
return SUCCESS;
|
||||
|
||||
default:
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue