38static inline double php_intpow10(
int power) {
40 if (power < 0 || power > 22) {
41 return pow(10.0, (
double)power);
44 static const double powers[] = {
45 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, 1e10, 1e11,
46 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19, 1e20, 1e21, 1e22};
52static zend_always_inline double php_round_get_basic_edge_case(
double integral,
double exponent,
int places)
55 ? fabs((integral + copysign(0.5, integral)) / exponent)
56 : fabs((integral + copysign(0.5, integral)) * exponent);
59static zend_always_inline double php_round_get_zero_edge_case(
double integral,
double exponent,
int places)
62 ? fabs((integral) / exponent)
63 : fabs((integral) * exponent);
68static inline double php_round_helper(
double integral,
double value,
double exponent,
int places,
int mode) {
69 double value_abs = fabs(
value);
74 edge_case = php_round_get_basic_edge_case(integral, exponent, places);
75 if (value_abs >= edge_case) {
84 return integral + copysign(1.0, integral);
90 edge_case = php_round_get_basic_edge_case(integral, exponent, places);
91 if (value_abs > edge_case) {
92 return integral + copysign(1.0, integral);
98 edge_case = php_round_get_zero_edge_case(integral, exponent, places);
99 if (
value > 0.0 && value_abs > edge_case) {
100 return integral + 1.0;
106 edge_case = php_round_get_zero_edge_case(integral, exponent, places);
108 return integral - 1.0;
117 edge_case = php_round_get_zero_edge_case(integral, exponent, places);
118 if (value_abs > edge_case) {
119 return integral + copysign(1.0, integral);
125 edge_case = php_round_get_basic_edge_case(integral, exponent, places);
126 if (value_abs > edge_case) {
127 return integral + copysign(1.0, integral);
128 }
else if (
UNEXPECTED(value_abs == edge_case)) {
129 bool even = !
fmod(integral, 2.0);
135 return integral + copysign(1.0, integral);
142 edge_case = php_round_get_basic_edge_case(integral, exponent, places);
143 if (value_abs > edge_case) {
144 return integral + copysign(1.0, integral);
145 }
else if (
UNEXPECTED(value_abs == edge_case)) {
146 bool even = !
fmod(integral, 2.0);
149 return integral + copysign(1.0, integral);
176 exponent = php_intpow10(
abs(places));
205 if ((places > 0 ? tmp_value2 / exponent : tmp_value2 * exponent) ==
value) {
218 if (
abs(places) < 23) {
309 zval *case_name = zend_enum_fetch_case_name(
mode);
350 if (precision >= 0) {
357 if (mode_object !=
NULL) {
650 double num, base = 0;
767 digit = (c >=
'0' && c <=
'9') ? c -
'0'
768 : (c >=
'A' && c <=
'Z') ? c -
'A' + 10
769 : (c >=
'a' && c <=
'z') ? c -
'a' + 10
777 num = num * base + digit;
804 int invalidchars = 0;
810 while (
s < e && isspace(*
s))
s++;
812 while (
s < e && isspace(*(e-1))) e--;
815 if (base == 16 &&
s[0] ==
'0' && (
s[1] ==
'x' ||
s[1] ==
'X'))
s += 2;
816 if (base == 8 &&
s[0] ==
'0' && (
s[1] ==
'o' ||
s[1] ==
'O'))
s += 2;
817 if (base == 2 &&
s[0] ==
'0' && (
s[1] ==
'b' ||
s[1] ==
'B'))
s += 2;
827 if (c >=
'0' && c <=
'9')
829 else if (c >=
'A' && c <=
'Z')
831 else if (c >=
'a' && c <=
'z')
845 if (num < cutoff || (num == cutoff && c <= cutlim)) {
846 num = num * base + c;
854 fnum = fnum * base + c;
858 if (invalidchars > 0) {
877 static const char digits[] =
"0123456789abcdefghijklmnopqrstuvwxyz";
882 if (base < 2 || base > 36) {
897 return zend_string_init(
ptr,
end -
ptr, 0);
908 static const char digits[] =
"0123456789abcdefghijklmnopqrstuvwxyz";
919 len = ((
sizeof(
value) * 8 - zend_ulong_nlz(
value)) + (base_log2 - 1)) / base_log2;
922 ret = zend_string_alloc(
len, 0);
928 *--
ptr = digits[
value & ((1 << base_log2) - 1)];
943 static const char digits[] =
"0123456789abcdefghijklmnopqrstuvwxyz";
952 char buf[(
sizeof(double) << 3) + 1];
964 *--
ptr = digits[(int)
fmod(fvalue, base)];
966 }
while (
ptr >
buf && fabs(fvalue) >= 1);
968 return zend_string_init(
ptr,
end -
ptr, 0);
1078 if (frombase < 2 || frombase > 36) {
1082 if (tobase < 2 || tobase > 36) {
1104 size_t dec_point_len,
const char *thousand_sep,
size_t thousand_sep_len)
1113 int is_negative = 0;
1123 if (tmpbuf ==
NULL) {
1125 }
else if (!isdigit((
int)
ZSTR_VAL(tmpbuf)[0])) {
1130 if (is_negative && d == 0) {
1143 integral = (dp -
ZSTR_VAL(tmpbuf));
1151 integral = zend_safe_addmult((integral-1)/3, thousand_sep_len, integral,
"number formatting");
1160 reslen = zend_safe_addmult(reslen, 1, dec_point_len,
"number formatting");
1168 res = zend_string_alloc(reslen, 0);
1178 size_t declen = (dp ?
s - dp : 0);
1179 size_t topad = (size_t)dec > declen ? dec - declen : 0;
1191 memcpy(t + 1, dp + 1, declen);
1197 memcpy(t + 1, dec_point, dec_point_len);
1206 t -= thousand_sep_len;
1207 memcpy(t + 1, thousand_sep, thousand_sep_len);
1222 size_t dec_point_len,
const char *thousand_sep,
size_t thousand_sep_len)
1225 1, 10, 100, 1000, 10000,
1226 100000, 1000000, 10000000, 100000000, 1000000000,
1227#if SIZEOF_ZEND_LONG == 8
1228 10000000000, 100000000000, 1000000000000, 10000000000000, 100000000000000,
1229 1000000000000000, 10000000000000000, 100000000000000000, 1000000000000000000, 10000000000000000000ul
1230#elif SIZEOF_ZEND_LONG > 8
1231# error "Unknown SIZEOF_ZEND_LONG"
1235 int is_negative = 0;
1259 if (dec < -(
sizeof(powers) /
sizeof(powers[0]) - 1)) {
1262 power = powers[-dec];
1263 power_half = power / 2;
1264 rest = tmpnum % power;
1265 tmpnum = tmpnum / power;
1267 if (rest >= power_half) {
1268 tmpnum = tmpnum * power + power;
1270 tmpnum = tmpnum * power;
1285 reslen = zend_safe_addmult((reslen-1)/3, thousand_sep_len, reslen,
"number formatting");
1288 reslen += is_negative;
1294 reslen = zend_safe_addmult(reslen, 1, dec_point_len,
"number formatting");
1298 res = zend_string_alloc(reslen, 0);
1306 topad = (size_t)dec;
1316 memcpy(t + 1, dec_point, dec_point_len);
1324 if (thousand_sep && (++
count % 3) == 0 &&
s >=
ZSTR_VAL(tmpbuf)) {
1325 t -= thousand_sep_len;
1326 memcpy(t + 1, thousand_sep, thousand_sep_len);
1345 char *thousand_sep =
NULL, *dec_point =
NULL;
1346 size_t thousand_sep_len = 0, dec_point_len = 0;
1356 if (dec_point ==
NULL) {
1360 if (thousand_sep ==
NULL) {
1362 thousand_sep_len = 1;
1374 (
Z_DVAL_P(num) >= 4503599627370496.0 ||
Z_DVAL_P(num) <= -4503599627370496.0)
1415 double dividend, divisor;
1429 double base, exponent;
octdec(string $octal_string)
hexdec(string $hex_string)
atan2(float $y, float $x)
fpow(float $num, float $exponent)
base_convert(string $num, int $from_base, int $to_base)
intdiv(int $num1, int $num2)
fdiv(float $num1, float $num2)
log(float $num, float $base=M_E)
strpbrk(string $string, string $characters)
count(Countable|array $value, int $mode=COUNT_NORMAL)
fmod(float $num1, float $num2)
pow(mixed $num, mixed $exponent)
bindec(string $binary_string)
hypot(float $x, float $y)
number_format(float $num, int $decimals=0, ?string $decimal_separator=".", ?string $thousands_separator=",")
zend_ffi_ctype_name_buf buf
#define round(tables, k1, k2)
PHPAPI ZEND_COLD void php_error_docref(const char *docref, int type, const char *format,...)
PHPAPI zend_long _php_math_basetolong(zval *arg, int base)
PHPAPI zend_string * _php_math_longtobase(zend_long arg, int base)
PHPAPI zend_string * _php_math_number_format_long(zend_long num, zend_long dec, const char *dec_point, size_t dec_point_len, const char *thousand_sep, size_t thousand_sep_len)
PHPAPI double _php_math_round(double value, int places, int mode)
PHPAPI zend_string * _php_math_zvaltobase(zval *arg, int base)
PHPAPI void _php_math_basetozval(zend_string *str, int base, zval *ret)
PHPAPI zend_string * _php_math_number_format(double d, int dec, char dec_point, char thousand_sep)
PHPAPI zend_string * _php_math_number_format_ex(double d, int dec, const char *dec_point, size_t dec_point_len, const char *thousand_sep, size_t thousand_sep_len)
PHPAPI int php_math_round_mode_from_enum(zend_object *mode)
unsigned const char * end
#define PHP_ROUND_TOWARD_ZERO
#define PHP_ROUND_HALF_UP
#define PHP_ROUND_HALF_DOWN
#define PHP_ROUND_HALF_EVEN
#define PHP_ROUND_AWAY_FROM_ZERO
#define PHP_ROUND_HALF_ODD
#define PHP_ROUND_CEILING
ZEND_API ZEND_COLD void zend_value_error(const char *format,...)
ZEND_API ZEND_COLD void zend_error(int type, const char *format,...)
ZEND_API ZEND_COLD void zend_argument_value_error(uint32_t arg_num, const char *format,...)
#define Z_PARAM_NUMBER(dest)
#define ZEND_PARSE_PARAMETERS_END()
#define ZEND_PARSE_PARAMETERS_NONE()
#define Z_PARAM_STR(dest)
#define Z_PARAM_STRING_OR_NULL(dest, dest_len)
#define ZEND_PARSE_PARAMETERS_START(min_num_args, max_num_args)
#define Z_PARAM_LONG(dest)
#define Z_PARAM_DOUBLE(dest)
#define Z_PARAM_ZVAL(dest)
#define Z_PARAM_OBJ_OF_CLASS_OR_LONG(dest_obj, _ce, dest_long)
zend_string_release_ex(func->internal_function.function_name, 0)
ZEND_API zend_class_entry * zend_ce_arithmetic_error
ZEND_API zend_class_entry * zend_ce_division_by_zero_error
ZEND_API ZEND_COLD zend_object * zend_throw_exception_ex(zend_class_entry *exception_ce, zend_long code, const char *format,...)
#define ZEND_FRAMELESS_FUNCTION(name, arity)
#define Z_FLF_PARAM_LONG(arg_num, dest)
struct _zend_string zend_string
ZEND_API zend_result ZEND_FASTCALL pow_function(zval *result, zval *op1, zval *op2)
#define ZEND_DOUBLE_FITS_LONG(d)
#define zend_always_inline
#define ZEND_UNREACHABLE()
#define EMPTY_SWITCH_DEFAULT_CASE()
#define UNEXPECTED(condition)
struct _zend_class_entry zend_class_entry
struct _zend_object zend_object
#define ZEND_LONG_INT_OVFL(zlong)
#define ZEND_LONG_INT_UDFL(zlong)
#define ZSTR_EMPTY_ALLOC()
ZEND_API double zend_strtod(const char *s00, const char **se)
#define Z_STRVAL_P(zval_p)
#define Z_STRLEN_P(zval_p)
#define ZVAL_DOUBLE(z, d)