今天在使用php写接口给前端返回数据时,使用round函数对一些数据进行保留两位有效数字操作,结果却大跌眼镜。。。
问题复现
$data['number'] = round(0.0322222,2);
echo json_encode($data);
//echo {"number":0.0299999999999999988897769753748434595763683319091796875}
解决方案1
将数字以字符串方式返回
$data['number'] = round(0.0322222,2).''; // 这里连接个空字符串将其整个变为字符串
echo json_encode($data); //echo {"number":"0.03"}
解决方案2
万一强迫症就是不想返回字符串,非要返回数字。比如我,安排
其实这个问题并不是因为round()引起的,划重点,是json_encode()引起的!!
禀着把我知道的都吐出来,看下相关源码:
static inline void php_json_encode_double(smart_str *buf, double d, int options) /* {{{ */
{
size_t len;
char num[PHP_DOUBLE_MAX_LENGTH];
php_gcvt(d, (int)PG(serialize_precision), '.', 'e', num);
len = strlen(num);
if (options & PHP_JSON_PRESERVE_ZERO_FRACTION && strchr(num, '.') == NULL && len < PHP_DOUBLE_MAX_LENGTH - 2) {
num[len++] = '.';
num[len++] = '0';
num[len] = '\0';
}
smart_str_appendl(buf, num, len);
}
其中有一个配置项值:serialize_precision,于是到php.ini中找一下配置项,发现我的值是100,将其改为(-1)。
别忘了重启php服务让其生效!!
$data['number'] = round(0.0322222,2);
echo json_encode($data); //echo "number":0.03}
大功告成。
究其原因
咋还跳着看呢,细看解决方案2去!