J'essaie d'imprimer les nombres entiers de 11 à 30 multipliés par 0,015
function round( number, step ) { const inverseStep = 1 / step; return Math.round( number * inverseStep ) / inverseStep; } for ( let i = 11; i <= 30; i++ ) { const rounded = round( i * 0.015, 0.015 ); console.log( `${i} * 0.015 = ${rounded}` ); }
Je m'attends à ce que la sortie ressemble à ceci:
11 * 0.015 = 0.16499999999999998 12 * 0.015 = 0.18 13 * 0.015 = 0.195 14 * 0.015 = 0.21 15 * 0.015 = 0.22499999999999998 16 * 0.015 = 0.24 17 * 0.015 = 0.255 18 * 0.015 = 0.27 19 * 0.015 = 0.285 20 * 0.015 = 0.3 21 * 0.015 = 0.315 22 * 0.015 = 0.32999999999999996 23 * 0.015 = 0.345 24 * 0.015 = 0.36 25 * 0.015 = 0.375 26 * 0.015 = 0.39 27 * 0.015 = 0.40499999999999997 28 * 0.015 = 0.42 29 * 0.015 = 0.435 30 * 0.015 = 0.44999999999999996
5 Réponses :
La précision en virgule flottante est suffisante pour faire le travail, il vous suffit de l'arrondir. Vous pouvez utiliser
.toFixed(2)
pour arrondir votre résultat à deux décimales.
Notez que cela convertit votre résultat en une chaîne (ce qui est bien pour ce que vous faites) donc si vous convertissez à nouveau en virgule flottante, l'inexactitude reviendra. Si vous êtes vraiment préoccupé par les valeurs exactes, vous devriez utiliser quelque chose comme Decimal.js qui gère les nombres comme des chaînes plutôt que des flottants. Surtout si vous faites quelque chose comme calculer de l'argent.
La fonction .toFixed ()
renvoie une chaîne, pas un nombre.
C'est vrai, mais il s'arrondit toujours correctement, donc si vous en avez besoin sous forme de nombre, lancez-le simplement. De toute façon, il imprime simplement les résultats, il en a donc besoin sous forme de chaîne
oui mais dès que vous le lancez, vous êtes de retour dans un pays à virgule flottante binaire, et ce n'est pas nécessairement la valeur exacte pour toutes les mêmes raisons.
C'est juste, mais à ce stade, vous ne devriez vraiment pas utiliser de virgule flottante de toute façon, et devriez utiliser quelque chose comme Decimal.js
en fonction des besoins, la personne doit l'imprimer, donc la conversion en String ne devrait pas être un problème dans ce cas, mais serait en effet utile comme mise à jour de votre réponse, quelque chose comme: Observation : (...)
Ce n'est pas avec javascript. Tout langage qui utilise la norme IEEE 754 pour représenter des nombres réels a cela. Fondamentalement, la plupart des nombres réels ne peuvent pas être représentés avec précision. Donc, une approximation (généralement 53 bits) est prise.
Ici, vous pouvez utiliser Number.toPrecision ().
53 bits, pas des chiffres!
Ouais, mon erreur.
En fonction de votre travail:
'11 * 0.015 = 0.165' '12 * 0.015 = 0.18' '13 * 0.015 = 0.195' '14 * 0.015 = 0.21' '15 * 0.015 = 0.225' '16 * 0.015 = 0.24' '17 * 0.015 = 0.255' '18 * 0.015 = 0.27' '19 * 0.015 = 0.285' '20 * 0.015 = 0.3' '21 * 0.015 = 0.315' '22 * 0.015 = 0.33' '23 * 0.015 = 0.345' '24 * 0.015 = 0.36' '25 * 0.015 = 0.375' '26 * 0.015 = 0.39' '27 * 0.015 = 0.405' '28 * 0.015 = 0.42' '29 * 0.015 = 0.435' '30 * 0.015 = 0.45'
votre sortie sera:
function round( number, step ) { const inverseStep = 1 / step; return Math.round( number * inverseStep ) / inverseStep; } for ( let i = 11; i <= 30; i++ ) { const rounded = round( i * 0.015, 0.001 ); console.log( `${i} * 0.015 = ${rounded}` ); }
À partir du duplicata: parseFloat ((i * 0.015) .toFixed (10))
effectue le travail sans le paramètre step . Les deux approches ont des limites.
Correct. J'essayais de me limiter à son exemple et à son code avec des changements minimes. @RobG J'ai voté pour votre commentaire :-)
Les gars ont fait un travail incroyable pourquoi cela se produit
Si vous devez encore le convertir en un nombre, vous pouvez utiliser Voici une belle explication de pourquoi cela se produit et différentes approches pour y faire face. parseFloat
avec le Number
dans lequel il convertit explicitement la valeur fournie en un nombre pour le traitement strong> for ( let i = 11; i <= 30; i++ ) {
console.log( `${i} * 0.015 = ${parseFloat(Number(i * 0.015).toFixed(3))}` );
}
Utilisation de l'astuce du facteur de correction.
$ cat num for ( let i = 11; i <= 30; i++ ) { let num = i * .015; num = num.toFixed(3); console.log( `${i} * 0.015 = ${num}` ); } $ node ./num 11 * 0.015 = 0.165 12 * 0.015 = 0.180 13 * 0.015 = 0.195 14 * 0.015 = 0.210 15 * 0.015 = 0.225 16 * 0.015 = 0.240 17 * 0.015 = 0.255 18 * 0.015 = 0.270 19 * 0.015 = 0.285 20 * 0.015 = 0.300 21 * 0.015 = 0.315 22 * 0.015 = 0.330 23 * 0.015 = 0.345 24 * 0.015 = 0.360 25 * 0.015 = 0.375 26 * 0.015 = 0.390 27 * 0.015 = 0.405 28 * 0.015 = 0.420 29 * 0.015 = 0.435 30 * 0.015 = 0.450
Utilisez l'option toFixed pour vous rapprocher si le remplissage à zéro ne vous dérange pas.
$ cat num let cf = 10 for ( let i = 11; i <= 30; i++ ) { let num = (i * cf) * (.015 * cf) / (cf *cf); console.log( `${i} * 0.015 = ${num}` ); } $ node ./num 11 * 0.015 = 0.165 12 * 0.015 = 0.18 13 * 0.015 = 0.195 14 * 0.015 = 0.21 15 * 0.015 = 0.225 16 * 0.015 = 0.24 17 * 0.015 = 0.255 18 * 0.015 = 0.27 19 * 0.015 = 0.285 20 * 0.015 = 0.3 21 * 0.015 = 0.315 22 * 0.015 = 0.33 23 * 0.015 = 0.345 24 * 0.015 = 0.36 25 * 0.015 = 0.375 26 * 0.015 = 0.39 27 * 0.015 = 0.405 28 * 0.015 = 0.42 29 * 0.015 = 0.435 30 * 0.015 = 0.45
Ce n'est pas du JavaScript, c'est chaque langage de programmation qui utilise la virgule flottante binaire moderne.
Ce n'est pas JS, cela s'applique à tous les langages de programmation. Découvrez docs.oracle.com/cd/E19957-01 /806-3568/ncg_goldberg.html