为什么楼层(0.99999999999999999)= 1楼(0.9999999999999999)= 0?

时间:2015-10-23 09:47:17

标签: php rounding floating-accuracy floor ceil

PHP中的

floor函数表现得很奇怪。 对于16个十进制值,它给出了底值,但是通过增加1位小数。

$int = 0.99999999999999999; 
echo floor($int); // returns 1 

$int = 0.9999999999999999; 
echo floor($int); // returns 0

$int = 0.99999999999999994; 
echo floor($int); // returns 0
  1. 是否在某处定义/解释,此时它会给出" round"值?
  2. 是否有任何函数可以给出0无论如何有多少9位小数?

2 个答案:

答案 0 :(得分:15)

这不是floor轮次,它是浮点数学。

这一行:

echo 0.99999999999999999;

打印1demo)因为0.99999999999999999太精确而无法用(64位?)浮点数表示,所以最接近可能的值,恰好是1
0.99999999999999994也过于精确,无法准确表示,但此处最接近的可表示值恰好为0.9999999999999999

  
      
  1. 是否在某处定义/解释,此时它给出“圆”值?
  2.   

这很复杂,但数字几乎总是四舍五入 我相信没有定义“从何时接近值”,但这是一个数学属性,它遵循IEEE 754 floating point standard中的定义。
为了安全起见,只要假设一切都是近似的。

  
      
  1. 是否有任何函数给出0无论如何有多少9位小数?
  2.   

没有。问题是,对于PHP,0.99999999999999999实际上与1相同 它们由完全相同的位序列表示,因此无法区分它们。

有一些解决方案可以使用更大的精度小数,但这需要一些主要的代码更改 您可能感兴趣:

Working with large numbers in PHP

请注意,虽然您可能获得任意精度,但您永远不会获得无限精度,因为这需要无限量的存储空间。

另请注意,如果您实际 处理无限精度,0.999...(永远进行)将真正(如在数学上可证明)相等至1this Wikipedia article深入解释。

答案 1 :(得分:0)

floor()

在我的开发机器上,行为发生在数字'15'而非'17'就像你的一样。 PHP舍入浮点数中的最后一位数。您的SET "stime=16:30:00.00" SET "etime=17:30:00.00" :start TASKLIST /FI "IMAGENAME EQ EXCEL.EXE" 2>NUL | FIND /I /N "EXCEL.EXE" >NUL IF %ERRORLEVEL% = 0 ( SET Erunning=true ) ELSE ( SET Erunning=false ) IF EXIST C:\Users\Hunter\Documents\HOMEWORKSHEETISOPEN.txt ( IF %Erunning%=false ( DEL C:\Users\Hunter\Documents\HOMEWORKSHEETISOPEN.txt ) ) IF EXIST C:\Users\Hunter\Documents\HOMEWORKSHEETISOPEN.txt ( SET running=true ) ELSE ( SET running=false ) FOR /F %%F IN ('wmic path win32_localtime get dayofweek^|Findstr [0-6]') DO SET DOW=%%F IF %time% GEQ %stime% IF %time% LEQ %etime% IF %running%==false IF %DOW% NEQ 6 IF %DOW% NEQ 0 ( START /MAX C:\Users\Hunter\OneDrive\Homework.xlsx ECHO IMRUNNING > C:\Users\Hunter\Documents\HOMEWORKSHEETISOPEN.txt ) TIMEOUT 60 /NOBREAK > NUL GOTO start 函数与此行为无关