Flyttal
Flyttalsnummer
Flyttalsnummer (även kända som "floats", "doubles" eller "riktiga tal") kan specificeras med något av följande syntaxer:
<?php
$a = 1.234;
$b = 1.2e3;
$c = 7E-10;
$d = 1_234.567; // från och med PHP 7.4.0
?>
Formellt från och med PHP 7.4.0 (tidigare var understreck inte tillåtna):
LNUM [0-9]+(_[0-9]+)* DNUM ({LNUM}?"."{LNUM}) | ({LNUM}"."{LNUM}?) EXPONENT_DNUM (({LNUM} | {DNUM}) [eE][+-]? {LNUM}) Storleken på ett flyttal är plattformsberoende, även om ett maximum på cirka 1.8e308 med en precision på ungefär 14 decimaler är ett vanligt värde (det 64-bitars IEEE-formatet).
Varning
Precision av flyttal
Flyttalsnummer har begränsad precision. Även om det beror på systemet använder PHP vanligtvis IEEE 754 dubbel precision-format, vilket ger ett maximalt relativt fel på grund av avrundning i storleksordningen 1.11e-16. Icke-elementära aritmetiska operationer kan ge större fel, och naturligtvis måste felfortplantning beaktas när flera operationer samlas.
Dessutom har rationella tal som exakt kan representeras som flyttal i bas 10, som 0,1 eller 0,7, inte en exakt representation som flyttal i bas 2, vilket används internt, oavsett storleken på mantissan. Därför kan de inte konverteras till sina interna binära motsvarigheter utan en liten precisionförlust. Detta kan leda till förvirrande resultat: till exempel kommer floor((0.1+0.7)*10) vanligtvis att returnera 7 istället för de förväntade 8, eftersom den interna representationen kommer att vara något som 7.9999999999999991118....
Så lita aldrig på flyttalsresultat till den sista siffran, och jämför inte flyttalsnummer direkt för likhet. Om högre precision är nödvändig, är funktioner för matematik med godtycklig precision och gmp-funktioner tillgängliga.
För en "enkel" förklaring, se » flyttalsguiden som också är titulerad "Varför stämmer inte mina nummer?"
Konvertering till flyttal
Från strängar
Om strängen är numerisk eller ledande numerisk kommer den att omvandlas till motsvarande flyttalsvärde, annars konverteras den till noll (0).
Från andra typer
För värden av andra typer utförs konverteringen genom att först konvertera värdet till int och sedan till flyttal. Se Konvertering till heltal för mer information.
Notera:
Eftersom vissa typer har odefinierat beteende när de konverteras till int, gäller detta också när de konverteras till flyttal.
Jämföra flyttal
Som noterat i varningen ovan är det problematiskt att testa flyttalsvärden för likhet, på grund av sättet som de representeras internt. Det finns dock sätt att göra jämförelser av flyttalsvärden som arbetar runt dessa begränsningar.
För att testa flyttalsvärden för likhet används en övre gräns på det relativa felet på grund av avrundning. Detta värde är känt som maskin epsilon, eller enhetsavrundning, och är den minsta acceptabla skillnaden i beräkningar. $a och $b är lika med 5 siffrors precision.
$a och $b är lika med 5 siffrors precision.
<?php $a = 1.23456789; $b = 1.23456780; $epsilon = 0.00001;
if(abs($a-$b) < $epsilon) {
echo "true";
}
?>
NaN
Vissa numeriska operationer kan resultera i ett värde representerat av konstanten NAN. Detta resultat representerar ett odefinierat eller orepresenterbart värde i flyttalsberäkningar. Alla lösa eller strikta jämförelser av detta värde mot något annat värde, inklusive sig själv, men med undantag av sant, kommer att ha ett resultat av falskt.
Eftersom NAN representerar ett antal olika värden, bör NAN inte jämföras med andra värden, inklusive sig själv, och istället bör kontrolleras med användning av is_nan().