Je suis contre l'avis précédent !
Je soupçonne très fortement que:
0.5384615384615384 provienne de 7/13
et
0.07692307692307693 provienne de 1/13
Si tel est réellement le cas, alors la bonne réponse est 7/13 / 1/13 = 7/13 * 13/1 = 7. C'est excel qui a raison.
Ceci montre une chose, c'est que les notions d'arrondis sont très sensibles, et surtout, peuvent intervenir à toutes et n'importe quelles étapes du calcul.
Techniquement, le seul moyen d'éviter les erreurs d'arrondi, c'est de ne surtout pas utiliser de nombres à virgule flottante, car quelque soit la précision il y a toujours un risque. C'est inhérant à la façon qu'on a de représenter les nombres à virgule flottante en informatique, et le même problème se pose avec tous les langages de programmation et tous les processeurs, pas seulement JavaScript ou les processeurs x86 ou x64. Je ne vais pas faire de blabla sur le binaire, la représentation des nombres selon IEE754 ou la notation positionnelle car il faudrait un tutoriel entier mais ceux qui connaissent les trois ont compris où je veux en venir, les erreurs sont inévitables. IL y a simplement des cas où elles sont plus ou moins acceptables (physique, simulation) et des cas où elles ne le sont pas (finances notamment).
A la place, il faut utiliser une représentation en virgule fixe, c'est ce que font les classes du type BigDecimal.
Pour info, la précision des nombres en JavaScript se situe entre 14 et 16 décimales le plus souvent, car utilisant en interne le type double sur 64 bits selon la norme IEE754. Très probablement la même qu'excel en fait. D'ailleurs les nombres que tu proposes ont comme par hasard exactement cette précision.
Excel est peut-être juste un peu plus malin, il arrive peut-être à constater que ce que tu lui as donné en entrée ne sont autres que des nombres périodiques artificiellement arrondis. Un algorithme simple pour le découvrir pourrait être le suivant:
1. A l'aide de regex, on peut trouver une périodicité, p.ex. pour 0.5384615384615384 on tombe sur 538461. Trouvable avec une regex du style (\d+)\1+
2. Pour trouver la valeur, on prend 538461 en numérateur, et comme dénominateur on prend un nombre de la même longueur avec que des 9, donc ici 538461/999999
3. En simplifiant on tombe sur 7/13 (538461 = 3^3 * 7^2 * 11 * 37 et 999999 = 3^3 * 7 * 11 * 13 * 37)
Mon avis est différent mais ma conclusion est la même:
Si la précision est importante pour toi, utilise toujours ces classes spécialisées, et comme les nombres à virgule flottante sont utilisés par défaut et inévitables en JavaScript, n'effectue jamais de division ou de multiplication sans elles.
Modifié par QuentinC (30 Aug 2016 - 14:59)