1
votes

Comment multiplier les nombres entiers entre 11 et 30 par 0,015?

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


2 commentaires

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


5 Réponses :


1
votes

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.


5 commentaires

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 : (...)



0
votes

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 ().


2 commentaires

53 bits, pas des chiffres!


Ouais, mon erreur.



0
votes

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}` );
}


2 commentaires

À 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 :-)



0
votes

Les gars ont fait un travail incroyable pourquoi cela se produit Si vous devez encore le convertir en un nombre, vous pouvez utiliser 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))}` );
}

Voici une belle explication de pourquoi cela se produit et différentes approches pour y faire face.

Référence et explication


0 commentaires

0
votes

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


0 commentaires