Perché non solo la matematica mobile è imperfetta, a volte la sua rappresentazione is flawed too - e questo è il caso qui.
In realtà non ottiene 0.1, 0.2, ... - e questo è abbastanza facile da controllare:
$start = 0;
$stop = 1;
$step = ($stop - $start)/10;
$i = $start + $step;
while ($i < $stop) {
print(number_format($i, 32) . "<br />");
$i += $step;
}
L'unica differenza, come vedete, è che echo
sostituito con number_format
chiamata. Ma i risultati sono drasticamente diversi:
0.10000000000000000555111512312578
0.20000000000000001110223024625157
0.30000000000000004440892098500626
0.40000000000000002220446049250313
0.50000000000000000000000000000000
0.59999999999999997779553950749687
0.69999999999999995559107901499374
0.79999999999999993338661852249061
0.89999999999999991118215802998748
0.99999999999999988897769753748435
Vedere? Solo una volta era 0.5
- perché quel numero può essere memorizzato in un contenitore float. Tutti gli altri erano solo approssimazioni.
Come risolvere questo? Bene, un approccio radicale sta usando non float, ma interi in situazioni simili. E 'facile notare che hai fatto in questo modo ...
$start = 0;
$stop = 10;
$step = (int)(($stop - $start)/10);
$i = $start + $step;
while ($i < $stop) {
print(number_format($i, 32) . "<br />");
$i += $step;
}
... che avrebbe funzionato bene:
In alternativa, è possibile utilizzare number_format
per convertire il galleggiante in qualche stringa, quindi confrontare questo stringa con galleggiante preformattato. In questo modo:
$start = 0;
$stop = 1;
$step = ($stop - $start)/10;
$i = $start + $step;
while (number_format($i, 1) !== number_format($stop, 1)) {
print(number_format($i, 32) . "\n");
$i += $step;
}
sorprendentemente, quando si divide l'intervallo in 20: $ step = ($ fermata - $ start)/20; è anche ok – user4035
Forse un errore a virgola mobile. – Blazemonger
correlati a http://stackoverflow.com/questions/3726721/php-math-precision – j08691