浮点到字符串部分工作,为什么在PHP中(字符串)将0.999999999999取整为1?

浮点到字符串部分工作,为什么在PHP中(字符串)将0.999999999999取整为1?,php,string,double,Php,String,Double,这个问题最好以代码块的形式提出。基本上,我需要知道为什么$float2在使用string转换为字符串时被舍入为1,并且还需要一种解决这个问题的方法。我可以在没有任何问题的情况下将其他浮点数转换为字符串,但是这一个正在进行舍入的情况引起了很大的麻烦 $float1 = 0.99999999999999; $float2 = 0.999999999999999; $float3 = 0.00000000000001; $float4 = 0.000000000000001;

这个问题最好以代码块的形式提出。基本上,我需要知道为什么$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.
   }
}
浮点数的大小取决于平台,但最大值为 大约为1.8e308,精度约为14位小数 通用值为64位IEEE格式

PHP上的精度是14位,第一个是14位,第二个是15位,超过了精度,所以它被舍入


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

不,它还不是1,因为我在其中的if子句证明了这一点。它还没有打印四舍五入完成,这意味着它还没有==1。这意味着是字符串进行舍入。我认为这是不对的,因为如果是,if子句将不会打印No-rounding done。因此,当相同的值被转换为字符串时,还会发生其他事情。在演员阵容的某个地方,它在做取整。所以,若字符串不能使用,那个么也许可以使用其他东西?我已经尝试过floor、bcadd、strval和floatval,所有这些都会导致四舍五入到1,但是if子句工作得很好。如果在将浮点转换为字符串之前将其存储在float中,则它将已经四舍五入。即$a=0.90000000000009将在我存储后立即四舍五入为1。尝试在ini中提高精度或使用ini_设置“精度”,20;你会看到它怎么会被四舍五入到1,然后不等于1?我不明白你在说什么。我有一个if子句要检查它是否被舍入,但它并不是从我的代码执行中显示出来的。然而,当我对它进行分类时,它确实进行了取整。我知道浮点数是四舍五入的,但它似乎是在字符串中发生的,而不是在浮点数本身上,这对我来说意味着它仍然可以被转换为字符串而不需要进一步四舍五入。如果你说的是真的,那就意味着它被四舍五入了两次,而这里的情况显然不是这样。所以我的问题是为什么弦要做四舍五入,为什么四舍五入发生在铸通弦上。在IEEE 754中,最接近0.9999999999999的64位二进制浮点是0.99999999999990009799277778373735911361873149871826171875,支持将四舍五入到1是由转换到字符串而不是原始赋值来完成的想法。