Parce que non seulement float mathématiques est imparfait, parfois, sa représentation est erronée, trop - ce qui est le cas ici.
Vous n'avez pas réellement obtenir 0.1, 0.2, ... - et c'est assez facile à vérifier:
$start = 0;
$stop = 1;
$step = ($stop - $start)/10;
$i = $start + $step;
while ($i < $stop) {
print(number_format($i, 32) . "<br />");
$i += $step;
}
La seule différence ici, comme vous le voyez, est-ce que echo
remplacé par number_format
appel. Mais les résultats sont radicalement différents:
0.10000000000000000555111512312578
0.20000000000000001110223024625157
0.30000000000000004440892098500626
0.40000000000000002220446049250313
0.50000000000000000000000000000000
0.59999999999999997779553950749687
0.69999999999999995559107901499374
0.79999999999999993338661852249061
0.89999999999999991118215802998748
0.99999999999999988897769753748435
Voir? Une seule fois il a été 0.5
- ce parce que le nombre peut être stocké dans un flotteur conteneur. Tous les autres sont seulement des approximations.
Comment résoudre ce problème? Eh bien, une approche radicale est d'utiliser non pas les chars, mais des entiers dans des situations similaires. Il est facile de remarquer qu'avez-vous fait de cette manière...
$start = 0;
$stop = 10;
$step = (int)(($stop - $start) / 10);
$i = $start + $step;
while ($i < $stop) {
print(number_format($i, 32) . "<br />");
$i += $step;
}
... il serait de travailler sur ok:
Alternativement, vous pouvez utiliser number_format
pour convertir le flotteur dans une chaîne de caractères, puis de comparer cette chaîne avec préformaté flotteur. Comme ceci:
$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;
}