PHP 和 MySQL 中用于存储偶尔的小数值的浮点精度问题

Floating point precision issue in PHP and MySQL for storing occasional decimal values

我想在我的 MySQL 数据库中偶尔存储十进制值,并在我的 PHP 应用程序中显示它们。让我解释一下,偶尔的十进制值是什么意思。这些数字在大多数情况下都是整数,就像整数一样。例如,160 或 170 等。但有时我需要保存 98.6 等值。

首先我在数据库中使用了 DECIMAL(4,1) 数据类型,我发现我总是得到这样的数字:160.0、170.0 和 98.6 等。所以,我将其更改为 FLOAT。在我的本地环境中,我在 PHP 应用程序和 phpMyAdmin 上看到数字为 160、170、98.6 等。但是在我的生产环境中,我在 phpMyAdmin 上看到了 160、170、98.6 等数字。但是在 PHP 应用程序中,我看到了 160、170、98.599998474121 等数字。

现在我需要决定是切换回 decimal 还是继续使用 float。无论哪种方式,我都需要找到一种解决方案来将数字转换为这样的格式:160、170 和 98.6 等。

您认为哪个更好:decimalfloat?如果数字的小数部分为零(使用 decimal 时),将数字转换为整数的最佳方法是什么?将 98.599998474121 等浮点值转换为 98.6 的最佳方法是什么?

如果数字的小数部分为零,则将数字转换为整数:

<?php
if (fmod($number, 1) == 0) {
    $number = intval($number)
}

有没有更好的方法?

理解浮点数不是一个精确的十进制数,而是一个接近它的值。它的存储方式非常有效,但代价是不准确。在不知道您的确切需求的情况下,一种可能的解决方案是将数字存储为浮点数并将它们四舍五入到一位小数。

// the casts are there just for the demonstration, you probably don't need them
$number = "170";
echo round((float)$number, 1); // gives 170
$number = "98.6";
echo round((float)$number, 1); // gives 98.6

浮点数以您希望的方式表示整数,并且仅当您存储某些小数时它们才会失去精度。

我也遇到了这个错误。 (阅读此 http://www.leaseweblabs.com/2013/06/the-php-floating-point-precision-is-wrong-by-default/

这是一个 php 相关的错误。

如果你确定你的小数部分最多只有一位,而你遇到更多,你就知道你需要重新处理数字

你可以这样得到精度:

function precision($num) { 
   return strlen(substr($num, strpos($num, '.')+1)); 
}