J'avoue ne pas comprendre. J'ai re-testé avec 9,99 == (10,0 - 0,01), c'est vrai, mais pas avec cette opération, vraiment bizarre
La notation en virgule flottante représente un nombre décimal sous la forme nombre = M x 2^E (c'est un peu plus compliqué, mais c'est le principe qui importe).
voir
http://babbage.cs.qc.edu/IEEE-754/Decimal.html
Sauf que cette représentation entraîne des approximations et que 9.99 est en fait représenté sous la forme une forme hexadécimale qui représente en fait le nombre 9.99000000000000021316 .
$r1 = 9.91;
printf("%01.20f<br>", $r1);
//9.91000000000000014211
$r2 = 19.90;
printf("%01.20f<br>", $r2);
//19.89999999999999857891
$r3 = 9.99;
printf("%01.20f<br>", $r3);
//9.99000000000000021316
$r4 = $r2 - $r1;
printf("%01.20f<br>", $r4);
//9.98999999999999843681
Les opérations arithmétiques ne se font pas à notre manière humaine en mettant les chiffres les uns en dessous des autres, mais avec des algorithmes qui travaillent directement sur les représentations hexadécimales des nombres en virgule flottante. Et ces algos introduisent eux aussi leur lot d'approximation.
Donc, en représentation interne, 19.90 - 9.91 est différent de 9.99. Par contre le programme echo chargé d'afficher un nombre comporte un mécanisme d'arrondi qui fait que 9.99000000000000021316 et 9.98999999999999843681 seront tous les deux affichés sous la forme 9.99.
D'où notre impression que c'est identique alors que ça ne l'est pas.
Ce mécanisme est bien connu de tous ceux qui bossent dans la finance. Si un article à 9.99€ est stocké sous la forme 9.9900000000000002€, on aura un décalage de 2 centimes quand on aura traité un stock de quelques millions de pièces. Et ça, pour un comptable, c'est inacceptable.
C'est pour ça que dans certains langages, on a la notion de nombre décimal différente de nombre à virgule flottante. Les nombres décimaux sont stockés avec leur valeur exacte (9.99) quasiment sous forme de chaîne de caractères et les opérations arithémétiques se font grosso-modo à la manière humaine.