diff --git a/Zend/zend_strtod.c b/Zend/zend_strtod.c index 3e7f90378ef5e..43122ccd2c0f5 100644 --- a/Zend/zend_strtod.c +++ b/Zend/zend_strtod.c @@ -3779,8 +3779,8 @@ ZEND_API char *zend_dtoa(double dd, int mode, int ndigits, int *decpt, bool *sig #endif u.d = dd; - if (word0(&u) & Sign_bit) { - /* set sign for everything, including 0's and NaNs */ + if (!zend_isnan(dd) && word0(&u) & Sign_bit) { + /* set sign for everything, including 0's */ *sign = 1; word0(&u) &= ~Sign_bit; /* clear sign bit */ } @@ -3791,7 +3791,7 @@ ZEND_API char *zend_dtoa(double dd, int mode, int ndigits, int *decpt, bool *sig #ifdef IEEE_Arith if ((word0(&u) & Exp_mask) == Exp_mask) #else - if (word0(&u) == 0x8000) + if (word0(&u) == 0x8000) #endif { /* Infinity or NaN */ diff --git a/ext/standard/formatted_print.c b/ext/standard/formatted_print.c index a98d410a228f8..912c30c8c06c6 100644 --- a/ext/standard/formatted_print.c +++ b/ext/standard/formatted_print.c @@ -243,17 +243,12 @@ php_sprintf_appenddouble(zend_string **buffer, size_t *pos, } if (zend_isnan(number)) { - is_negative = (number<0); - php_sprintf_appendstring(buffer, pos, "NaN", 3, 0, padding, - alignment, 3, is_negative, 0, always_sign); - return; + always_sign = 0; + padding = ' '; } if (zend_isinf(number)) { - is_negative = (number<0); - php_sprintf_appendstring(buffer, pos, "INF", 3, 0, padding, - alignment, 3, is_negative, 0, always_sign); - return; + padding = ' '; } switch (fmt) { diff --git a/ext/standard/math.c b/ext/standard/math.c index 5b2d74a2de9e8..82fe28916720e 100644 --- a/ext/standard/math.c +++ b/ext/standard/math.c @@ -1026,7 +1026,7 @@ PHPAPI zend_string *_php_math_number_format_ex(double d, int dec, const char *de int count = 0; int is_negative=0; - if (d < 0) { + if (d < 0 && !zend_isinf(d)) { is_negative = 1; d = -d; } diff --git a/ext/standard/tests/bug49244.phpt b/ext/standard/tests/bug49244.phpt index a50aacee8d086..2032407dd3848 100644 --- a/ext/standard/tests/bug49244.phpt +++ b/ext/standard/tests/bug49244.phpt @@ -10,23 +10,23 @@ for ($i = 0; $i < 10; $i++) { ?> --EXPECT-- -{NaN} NaN -{NaN} NaN -{NaN} NaN -{NaN} NaN -{NaN} NaN -{NaN} NaN -{NaN} NaN -{NaN} NaN -{NaN} NaN -{NaN} NaN -{NaN} NaN -{NaN} NaN -{NaN} NaN -{NaN} NaN -{NaN} NaN -{NaN} NaN -{NaN} NaN -{NaN} NaN -{NaN} NaN -{NaN} NaN +{NAN} NAN +{NAN} NAN +{NAN} NAN +{NAN} NAN +{NAN} NAN +{NAN} NAN +{NAN} NAN +{NAN} NAN +{NAN} NAN +{NAN} NAN +{NAN} NAN +{NAN} NAN +{NAN} NAN +{NAN} NAN +{NAN} NAN +{NAN} NAN +{NAN} NAN +{NAN} NAN +{NAN} NAN +{NAN} NAN diff --git a/ext/standard/tests/strings/number_format_basic.phpt b/ext/standard/tests/strings/number_format_basic.phpt index 2e54eb1f0d5ae..cc90339c46f13 100644 --- a/ext/standard/tests/strings/number_format_basic.phpt +++ b/ext/standard/tests/strings/number_format_basic.phpt @@ -14,7 +14,10 @@ $values = array(1234.5678, "123.456789", "12.3456789e1", true, - false); + false, + INF, + -INF, + NAN); echo "\n-- number_format tests.....default --\n"; for ($i = 0; $i < count($values); $i++) { @@ -55,6 +58,9 @@ string(3) "123" string(3) "123" string(1) "1" string(1) "0" +string(3) "inf" +string(4) "-inf" +string(3) "nan" -- number_format tests.....with two dp -- string(8) "1,234.57" @@ -68,6 +74,9 @@ string(6) "123.46" string(6) "123.46" string(4) "1.00" string(4) "0.00" +string(3) "inf" +string(4) "-inf" +string(3) "nan" -- number_format tests.....English format -- string(8) "1 234.57" @@ -81,6 +90,9 @@ string(6) "123.46" string(6) "123.46" string(4) "1.00" string(4) "0.00" +string(3) "inf" +string(4) "-inf" +string(3) "nan" -- number_format tests.....French format -- string(8) "1 234,57" @@ -94,3 +106,6 @@ string(6) "123,46" string(6) "123,46" string(4) "1,00" string(4) "0,00" +string(3) "inf" +string(4) "-inf" +string(3) "nan" diff --git a/ext/standard/tests/strings/printf_inf_nan.phpt b/ext/standard/tests/strings/printf_inf_nan.phpt new file mode 100644 index 0000000000000..ccd8f12472210 --- /dev/null +++ b/ext/standard/tests/strings/printf_inf_nan.phpt @@ -0,0 +1,123 @@ +--TEST-- +Test printf INF/-INF/NAN rendering +--FILE-- + +--EXPECT-- +#INF# #INF# #INF# #INF# #INF# #INF# #INF# #INF# +#INF# #INF# #INF# #INF# #INF# #INF# #INF# #INF# +#-INF# #-INF# #-INF# #-INF# #-INF# #-INF# #-INF# #-INF# +#-INF# #-INF# #-INF# #-INF# #-INF# #-INF# #-INF# #-INF# +#NAN# #NAN# #NAN# #NAN# #NAN# #NAN# #NAN# #NAN# +#NAN# #NAN# #NAN# #NAN# #NAN# #NAN# #NAN# #NAN# +#NAN# #NAN# #NAN# #NAN# #NAN# #NAN# #NAN# #NAN# +#+INF# #-INF# #NAN# #NAN# +# INF# # -INF# # NAN# # NAN# +# +INF# # -INF# # NAN# # NAN# +#INF # #-INF # #NAN # #NAN # +#+INF # #-INF # #NAN # #NAN # +# INF# # -INF# # NAN# # NAN# +# +INF# # -INF# # NAN# # NAN# +#INF # #-INF # #NAN # #NAN # +#+INF # #-INF # #NAN # #NAN # +# INF# # -INF# # NAN# # NAN# +# +INF# # -INF# # NAN# # NAN# +#INF # #-INF # #NAN # #NAN # +#+INF # #-INF # #NAN # #NAN # +# INF# # -INF# # NAN# # NAN# +# +INF# # -INF# # NAN# # NAN# +#INF # #-INF # #NAN # #NAN # +#+INF # #-INF # #NAN # #NAN # diff --git a/main/snprintf.c b/main/snprintf.c index d00fb83286e26..1b066343c23bb 100644 --- a/main/snprintf.c +++ b/main/snprintf.c @@ -291,7 +291,6 @@ PHPAPI char * php_conv_fp(char format, double num, if (isalpha((int)*p)) { *len = strlen(p); memcpy(buf, p, *len + 1); - *is_negative = false; free(p_orig); return (buf); } @@ -872,8 +871,13 @@ static size_t format_converter(buffy * odp, const char *fmt, va_list ap) /* {{{ s = "NAN"; s_len = 3; } else if (zend_isinf(fp_num)) { - s = "INF"; - s_len = 3; + if (fp_num > 0) { + s = "INF"; + s_len = 3; + } else { + s = "-INF"; + s_len = 4; + } } else { #ifdef ZTS localeconv_r(&lconv); diff --git a/main/spprintf.c b/main/spprintf.c index f4faf0d894c5e..eac3df59df11b 100644 --- a/main/spprintf.c +++ b/main/spprintf.c @@ -582,8 +582,13 @@ static void xbuf_format_converter(void *xbuf, bool is_char, const char *fmt, va_ s = "nan"; s_len = 3; } else if (zend_isinf(fp_num)) { - s = "inf"; - s_len = 3; + if (fp_num > 0) { + s = "inf"; + s_len = 3; + } else { + s = "-inf"; + s_len = 4; + } } else { #ifdef ZTS localeconv_r(&lconv);