首页 > 解决方案 > 浮动到字符串部分工作,为什么(字符串)在 PHP 中将 0.999999999999999 舍入为 1?

问题描述

这个问题最好以代码块的形式提出。基本上,我需要知道为什么 $float2 在使用 (string) 转换为字符串时会被舍入为 1,并且还需要一种解决此问题的方法。我可以毫无问题地将其他浮点数转换为字符串,但是这种发生舍入的情况引起了严重的头痛。

   $float1 = 0.99999999999999;
   $float2 = 0.999999999999999;
   $float3 = 0.00000000000001;
   $float4 = 0.000000000000001;
   echo $str1 = float_to_string($float1);
   echo ' type: '.gettype($str1)."\n"; //Echos:  0.99999999999999 type: string


   echo $str2 = float_to_string($float2);
   echo ' type: '.gettype($str2)."\n"; //Echos: 1 type: string

   echo $str3 = float_to_string($float3);
   echo ' type: '.gettype($str3)."\n"; //Echos: 0.00000000000001 type: string

   echo $str4 = float_to_string($float4);
   echo ' type: '.gettype($str4)."\n"; //Echos: 0.000000000000001 type: string


   if ($float2 != 1)
   {
      echo "No rounding done in if clause so this means that (string) is doing the rounding.\n";
   }

function float_to_string($float)
{
   $parts = explode('E', $float);
   if(count($parts) === 2)
   {
      $exp = abs(end($parts)) + strlen($parts[0]);
      $decimal = number_format($float, $exp);  //This converts it to a string
      echo "Returning with number_format\n";
      return rtrim($decimal, '.0');
   }
   else
   {
      echo "Returning without number_format\n";
      return (string)$float; //Why is this rounding 0.999999999999999 to 1?!  I thought only number_format did rounding.
   }
}

标签: phpstringdouble

解决方案


浮点数的大小取决于平台,尽管最大约为 1.8e308 且精度约为 14 位十进制数字是常用值(64 位 IEEE 格式)。

https://www.php.net/manual/en/language.types.float.php

PHP 的精度是 14 位,你的第一个是 14 位,第二个是 15 并且超过了精度,所以它被四舍五入。

此外,我相信您可以将 ini 中的精度设置为超过 14 位,但由于浮点数的工作方式,您的数学最终可能不准确。


推荐阅读