[JAVA] La fraction n'est-elle pas mauvaise en programmation? L'histoire.

Il faut faire très attention lors du traitement des fractions dans la programmation. Je suis sûr que certains d'entre vous ont commencé à écrire des programmes de travail ce printemps, donc dans le but d'attirer l'attention, je vais l'expliquer d'une manière facile à comprendre avec des raisons. C'est de notoriété publique pour ceux qui le savent, mais c'est un gros écueil pour ceux qui ne le savent pas. Si quelqu'un semble savoir à quel point c'est dangereux, faites-le moi savoir.

Pourquoi les fractions sont-elles dangereuses?

L'essentiel est que les ordinateurs traitent les nombres en binaire, tandis que le monde réel calcule principalement en décimal. Il est dangereux de calculer la fraction lors de la conversion de la base.

Alors, pourquoi est-il dangereux de gérer des fractions lors de la conversion de radix? Parlons d'abord des nombres ternaires et décimaux.

Quel est le nombre ternaire 0,1?

Le nombre ternaire 0,1 est un nombre qui devient 1 lorsqu'il est ajouté 3 fois. 0,1 + 0,1 = 0,2 0,2 + 0,1 est porté à 1. Exprimé en fractions, il est de 1/3. Alors, qu'est-ce que 1/3 en décimal? Un nombre qui devient 1 lorsqu'il est ajouté 3 fois. C'est 0,333333333333333333 ・ ・ ・ ・ ・ ・ C'est une fraction infinie. 0,1, qui était une fraction finie en nombres ternaires, devient une fraction infinie en nombres décimaux. Et comme les ressources informatiques sont limitées, elles ne peuvent pas contenir des fractions infinies. Le type à virgule flottante 64 bits peut contenir jusqu'à 16 chiffres. Par conséquent, lorsqu'un ordinateur a une fraction, il peut avoir une valeur approximative. Si l'ordinateur avait des nombres décimaux, 1/3 serait conservé sous la forme 0,33333333333333333. C'est dangereux.

Une valeur qui ne peut pas être exprimée en binaire.

J'ai décrit que le nombre de fractions qui peuvent être exprimées diffère selon la base, en utilisant 1/3 comme exemple. Alors, qu'est-ce qu'un nombre décimal qui devient une fraction infinie en binaire? Par exemple, le nombre décimal 0,2 ne peut pas être représenté en binaire. 0 .001100110011 ... Et devient une fraction infinie. PDF de la page mathemaTeX de tmt! explique en détail pourquoi il devient 0.001100110011 .... Ainsi, le nombre décimal 0,2 ne peut pas être tenu exactement par un ordinateur (une variable à virgule flottante normale). Il aura une valeur approximative.

Une erreur de calcul se produit.

Cela pose des problèmes lors du traitement des fractions en programmation.

const num = 0.2 + 0.1;
console.log("0.2 + 0.1 = " + num);
> 0.2 + 0.1 = 0.30000000000000004

Il devrait être de 0,3, mais il a augmenté de 0,0000000000000000004. C'est le problème. Si vous utilisez des fractions pour les calculs de répartition, vous risquez d'obtenir une facturation erronée. C'est horrible.

Alors que devons-nous faire?

Au lieu de traiter des fractions avec des variables régulières, calculons via la bibliothèque. Pour JavaScript, utilisez BigDecimal.js ou bignumber.js .. En Java, calculons à l'aide de la classe BigDecimal de la bibliothèque standard. Dans d'autres langues, il existe des bibliothèques avec des noms tels que "Big Decimal" et "decimal".

Conclusion

Si vous souhaitez calculer la fraction avec précision, calculons-la via la bibliothèque. Cependant, lorsqu'il n'est pas nécessaire de calculer si précisément, comme le calcul de la hauteur de dessin, il peut être préférable de calculer avec des variables simples plutôt qu'avec la bibliothèque. En effet, la bibliothèque peut sacrifier la vitesse pour calculer avec précision.

c'est tout.

Recommended Posts

La fraction n'est-elle pas mauvaise en programmation? L'histoire.
L'histoire de l'apprentissage de Java dans la première programmation
Quelles sont les règles de JUnit?
Histoire de refactoring de rails apprise sur le terrain
L'histoire de l'écriture de Java dans Emacs
L'histoire de la comparaison de chaînes de bas niveau en Java
L'histoire de la fabrication d'un Othello ordinaire à Java
Une histoire sur le JDK à l'ère de Java 11