pinguo / php-msf-demo

GNU General Public License v2.0
72 stars 41 forks source link

Docker镜像下output小数 BUG #43

Closed gvzhang closed 6 years ago

gvzhang commented 6 years ago

运行环境:Docker镜像

运行代码:

namespace App\Controllers;
use PG\MSF\Controllers\Controller;
class Welcome extends Controller
{
    public function actionIndex()
    {
        $divide = 58/100;
        $this->output($divide);
    }
}

输出结果:0.57999999999999996

期待结果:0.58

后来发现是Docker镜像下的php版本问题。在Docker环境里面运行下面的代码就会出现上述问题。

<?php
$total = 58;
echo json_encode($total/100.00, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
$ php test.php
0.57999999999999996

看来要更新下Docker镜像的PHP版本。

shellvon commented 6 years ago

这个和 PHP 以及 Docker 版本没关系,精度依赖于你的系统。你应该了解一下浮点数怎么存的。 关于 PHP 的资料,可以参见这里: http://php.net/manual/en/language.types.float.php#warn.float-precision

gvzhang commented 6 years ago

@shellvon 谢谢提醒。还有就是在进入到json_encode才会出现精度问题,把json_encode这段代码注释掉就没问题的。end函数is_string要不要多加个判断条件?

    public function end($output = '', $httpCode = 200, $gzip = true)
    {
        $this->setHeader('X-Ngx-LogId', $this->getContext()->getLogId());
        $this->getContext()->getLog()->pushLog('http-code', $httpCode);
        $acceptEncoding = strtolower($this->request->header['accept-encoding'] ?? '');
        if ($gzip && strpos($acceptEncoding, 'gzip') !== false) {
            $this->response->gzip(1);
        }

        if (!is_string($output)) {
            $this->setHeader('Content-Type', 'application/json');
            $output = json_encode($output, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
        }
        $this->getContext()->getLog()->pushLog('content-length', strlen($output));
        $this->setStatusHeader($httpCode);
        $this->response->end($output);
        $this->__isEnd = true;
    }