--- embedaddon/php/ext/standard/math.c 2012/02/21 23:48:02 1.1.1.1 +++ embedaddon/php/ext/standard/math.c 2014/06/15 20:03:57 1.1.1.4 @@ -2,7 +2,7 @@ +----------------------------------------------------------------------+ | PHP Version 5 | +----------------------------------------------------------------------+ - | Copyright (c) 1997-2012 The PHP Group | + | Copyright (c) 1997-2014 The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | @@ -19,7 +19,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: math.c,v 1.1.1.1 2012/02/21 23:48:02 misho Exp $ */ +/* $Id: math.c,v 1.1.1.4 2014/06/15 20:03:57 misho Exp $ */ #include "php.h" #include "php_math.h" @@ -37,7 +37,7 @@ static inline int php_intlog10abs(double value) { int result; value = fabs(value); - if (value < 1e-8 || value > 1e23) { + if (value < 1e-8 || value > 1e22) { result = (int)floor(log10(value)); } else { static const double values[] = { @@ -46,7 +46,7 @@ static inline int php_intlog10abs(double value) { 1e8, 1e9, 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19, 1e20, 1e21, 1e22}; /* Do a binary search with 5 steps */ - result = 16; + result = 15; if (value < values[result]) { result -= 8; } else { @@ -620,7 +620,7 @@ PHP_FUNCTION(pow) /* calculate pow(long,long) in O(log exp) operations, bail if overflow */ while (i >= 1) { - int overflow; + long overflow; double dval = 0.0; if (i % 2) { @@ -1094,6 +1094,13 @@ PHP_FUNCTION(base_convert) */ PHPAPI char *_php_math_number_format(double d, int dec, char dec_point, char thousand_sep) { + return _php_math_number_format_ex(d, dec, &dec_point, 1, &thousand_sep, 1); +} + +static char *_php_math_number_format_ex_len(double d, int dec, char *dec_point, + size_t dec_point_len, char *thousand_sep, size_t thousand_sep_len, + int *result_len) +{ char *tmpbuf = NULL, *resbuf; char *s, *t; /* source, target */ char *dp; @@ -1113,6 +1120,10 @@ PHPAPI char *_php_math_number_format(double d, int dec tmplen = spprintf(&tmpbuf, 0, "%.*F", dec, d); if (tmpbuf == NULL || !isdigit((int)tmpbuf[0])) { + if (result_len) { + *result_len = tmplen; + } + return tmpbuf; } @@ -1133,7 +1144,7 @@ PHPAPI char *_php_math_number_format(double d, int dec /* allow for thousand separators */ if (thousand_sep) { - integral += (integral-1) / 3; + integral += thousand_sep_len * ((integral-1) / 3); } reslen = integral; @@ -1142,7 +1153,7 @@ PHPAPI char *_php_math_number_format(double d, int dec reslen += dec; if (dec_point) { - reslen++; + reslen += dec_point_len; } } @@ -1178,7 +1189,8 @@ PHPAPI char *_php_math_number_format(double d, int dec /* add decimal point */ if (dec_point) { - *t-- = dec_point; + t -= dec_point_len; + memcpy(t + 1, dec_point, dec_point_len); } } @@ -1187,7 +1199,8 @@ PHPAPI char *_php_math_number_format(double d, int dec while(s >= tmpbuf) { *t-- = *s--; if (thousand_sep && (++count%3)==0 && s>=tmpbuf) { - *t-- = thousand_sep; + t -= thousand_sep_len; + memcpy(t + 1, thousand_sep, thousand_sep_len); } } @@ -1198,8 +1211,19 @@ PHPAPI char *_php_math_number_format(double d, int dec efree(tmpbuf); + if (result_len) { + *result_len = reslen; + } + return resbuf; } + +PHPAPI char *_php_math_number_format_ex(double d, int dec, char *dec_point, + size_t dec_point_len, char *thousand_sep, size_t thousand_sep_len) +{ + return _php_math_number_format_ex_len(d, dec, dec_point, dec_point_len, + thousand_sep, thousand_sep_len, NULL); +} /* }}} */ /* {{{ proto string number_format(float number [, int num_decimal_places [, string dec_seperator, string thousands_seperator]]) @@ -1224,21 +1248,20 @@ PHP_FUNCTION(number_format) RETURN_STRING(_php_math_number_format(num, dec, dec_point_chr, thousand_sep_chr), 0); break; case 4: - if (dec_point != NULL) { - if (dec_point_len) { - dec_point_chr = dec_point[0]; - } else { - dec_point_chr = 0; - } + if (dec_point == NULL) { + dec_point = &dec_point_chr; + dec_point_len = 1; } - if (thousand_sep != NULL) { - if (thousand_sep_len) { - thousand_sep_chr = thousand_sep[0]; - } else { - thousand_sep_chr = 0; - } + + if (thousand_sep == NULL) { + thousand_sep = &thousand_sep_chr; + thousand_sep_len = 1; } - RETURN_STRING(_php_math_number_format(num, dec, dec_point_chr, thousand_sep_chr), 0); + + Z_TYPE_P(return_value) = IS_STRING; + Z_STRVAL_P(return_value) = _php_math_number_format_ex_len(num, dec, + dec_point, dec_point_len, thousand_sep, thousand_sep_len, + &Z_STRLEN_P(return_value)); break; default: WRONG_PARAM_COUNT;