Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Formatage de nombre

7 réponses
Avatar
Gloops
Bonjour tout le monde,

Mettons que je veuille écrire le nombre 54 en binaire sur 8 chiffres.

ça va donner :

("00000000"+(54).toString(2)).substr(-8)

Est-ce que ça peut se simplifier ?
Bien entendu pour la lisibilité on peut déjà mettre ça dans une fonction
Binaire8Chiffres, ou si c'est pour le mettre en ligne Binary8Figures,
mais intrinsèquement je me demande si il n'y a pas déjà quelque chose à
faire.

En décimal aussi, en regardant la doc j'ai vu toPrecision() pour mettre
un nombre de chiffres donné, mais ... c'est en comptant ceux derrière la
virgule, je suis bien avec ça.
Comment dire ... C'est comme ça faut faire avec ?

7 réponses

Avatar
SAM
Le 09/08/16 à 17:06, Gloops a écrit :
Bonjour tout le monde,
Mettons que je veuille écrire le nombre

(snip)(et en passant sur la drôle d'idée de pas écrire "54")
Est-ce que ça peut se simplifier ?

SVP
essayer de faire tout ça côté serveur !
En JS on est confronté à des erreurs.
En cause, à ce que je crois avoir compris, d'une part le comptage en
hexa à traduire en base 10 pour les humains mais aussi les processeurs
qui comptent encore sous une autre base ... 64 bits
<http://www.mathieurobin.com/2011/10/les-nombres-en-javascript/>
voir : "Une petite dernière pour la route"
<http://forum.alsacreations.com/topic-5-71591-1-Resutat-calcul-etrange.html#p476977>
Cordialement,
--
Stéphane Moriaux avec/with iMac-intel 27" & Mac OS X 10.6.8
Avatar
Gloops
Le 09/08/2016 à 23:05, SAM a écrit :
Le 09/08/16 à 17:06, Gloops a écrit :
Bonjour tout le monde,
Mettons que je veuille écrire le nombre

(snip)(et en passant sur la drôle d'idée de pas écrire "54")

Justement, ça, c'était dans le snip ;)
Est-ce que ça peut se simplifier ?

SVP
essayer de faire tout ça côté serveur !

Côté serveur je ne vais pas m'embêter avec Javascript :)
En JS on est confronté à des erreurs.
En cause, à ce que je crois avoir compris, d'une part le comptage en
hexa à traduire en base 10 pour les humains mais aussi les processeurs
qui comptent encore sous une autre base ... 64 bits
<http://www.mathieurobin.com/2011/10/les-nombres-en-javascript/>

Assez décorative, la propriété .valueof(), non ?
voir : "Une petite dernière pour la route"

Ah, oui, celui-là est déjà signalé en plusieurs endroits.
Du coup je viens d'essayer de contourner ...
Le résultat de +0 + "0.1" + "0.2"
est assez cocasse aussi dans son genre.
(1.1 + 1.2) - 2
est faux aussi, mais différent de 0.1 + 0.2
J'imagine que ça doit être en projet quelque part de corriger tout ça ...
<http://forum.alsacreations.com/topic-5-71591-1-Resutat-calcul-etrange.html#p476977>

Si au moins on avait une exception qui signale le "mode taré" ...
Cordialement,

Aussi
Avatar
Gloops
Le 09/08/2016 à 23:05, SAM a écrit :
<http://www.mathieurobin.com/2011/10/les-nombres-en-javascript/>
voir : "Une petite dernière pour la route"

Je m'étais figuré que 0.1 + 0.2 était la blague potache des créateurs de
Javascript, et que pour le reste ils allaient se tenir à carreau.
Ah ben non,
0.1 + 0.3 + 0.2
est pas mal non plus ...
Avatar
Olivier Miakinen
Bonjour,
Le 10/08/2016 01:32, Gloops a écrit :
Je m'étais figuré que 0.1 + 0.2 était la blague potache des créateurs de
Javascript, et que pour le reste ils allaient se tenir à carreau.

Ce n'est pas une blague, c'est juste le prix à payer quand on utilise
des nombres décimaux représentés sous forme binaire (représentation
IEEE754 sur 64 bits dans le cas de JavaScript).
0.1 (décimal) 0.00011001100110011001100110011001100110011001100110011010 (ieee754)
3 × 0.1 (décimal) 0.00100110011001100110011001100110011001100110011001100111 (ieee754)
= 0.30000000000000004 (décimal)
0.3 (décimal) 0.00100110011001100110011001100110011001100110011001100110 (ieee754)
Mais quand on a besoin de manipuler des nombres décimaux, c'est-à-dire
où toutes les décimales à partir d'un certain rang sont nulles, la
plupart du temps cela revient à manipuler des nombres entiers, quitte
à les diviser par une puissance de 10 au moment de l'affichage. Par
exemple, au lieu de calculer des sommes en euros avec deux chiffres
après la virgule, il suffit de calculer ces mêmes sommes en centimes
d'euros, sans virgule : 3,50 ¤ = 350 centimes.
En effet, il faut savoir que *tous* les nombres entiers compris entre
-9007199254740992 et +9007199254740992 sont représentables dans IEEE754
64 bits (et donc dans JavaScript) sans aucune erreur d'arrondi. Cela
devrait suffire pour la plupart des besoins...
--
Olivier Miakinen
Avatar
Gloops
Le 22/08/2016 à 16:05, Olivier Miakinen a écrit :
Bonjour,
Le 10/08/2016 01:32, Gloops a écrit :
Je m'étais figuré que 0.1 + 0.2 était la blague potache des créateurs de
Javascript, et que pour le reste ils allaient se tenir à carreau.

Ce n'est pas une blague, c'est juste le prix à payer quand on utilise
des nombres décimaux représentés sous forme binaire (représentation
IEEE754 sur 64 bits dans le cas de JavaScript).
0.1 (décimal) > 0.00011001100110011001100110011001100110011001100110011010 (ieee754)
3 × 0.1 (décimal) > 0.00100110011001100110011001100110011001100110011001100111 (ieee754)
= 0.30000000000000004 (décimal)
0.3 (décimal) > 0.00100110011001100110011001100110011001100110011001100110 (ieee754)
Mais quand on a besoin de manipuler des nombres décimaux, c'est-à-dire
où toutes les décimales à partir d'un certain rang sont nulles, la
plupart du temps cela revient à manipuler des nombres entiers, quitte
à les diviser par une puissance de 10 au moment de l'affichage. Par
exemple, au lieu de calculer des sommes en euros avec deux chiffres
après la virgule, il suffit de calculer ces mêmes sommes en centimes
d'euros, sans virgule : 3,50 ¤ = 350 centimes.
En effet, il faut savoir que *tous* les nombres entiers compris entre
-9007199254740992 et +9007199254740992 sont représentables dans IEEE754
64 bits (et donc dans JavaScript) sans aucune erreur d'arrondi. Cela
devrait suffire pour la plupart des besoins...

Donc, on commet une erreur d'arrondi à la fin parce que la
représentation n'en a pas :)
Il n'y a que Javascript à faire le gag, ou je me trompe ?
Je m'étais dit que j'allais consacrer une demi-journée à comprendre
comment se bidouille cette affaire, mais ... il faut une demi-journée
disponible :)
Avatar
Olivier Miakinen
Le 22/08/2016 20:16, Gloops a écrit :
Je m'étais figuré que 0.1 + 0.2 était la blague potache des créateurs de
Javascript, et que pour le reste ils allaient se tenir à carreau.

Ce n'est pas une blague, c'est juste le prix à payer quand on utilise
des nombres décimaux représentés sous forme binaire (représentation
IEEE754 sur 64 bits dans le cas de JavaScript).
[...]

Donc, on commet une erreur d'arrondi à la fin parce que la
représentation n'en a pas :)

Euh... non. Ou alors je n'ai pas compris ce que tu veux dire.
Prenons un autre exemple plus simple, en supposant que la représentation
binaire a exactement 4 bits après la virgule (ce n'est pas comme ça que
fonctionne la norme IEEE754 mais on retrouvera le même problème).
Le premier bit après la virgule vaut 1/2 soit 0,5. Le second bit vaut
1/4 soit 0,25. Le troisième vaut 0,125 et le quatrième 0,0625. Du coup
les valeurs possibles entre 0 et 1 sont les suivantes :
binaire = décimal
0,0000 = 0
0,0001 = 0,0625
0,0010 = 0,125
0,0011 = 0,1875
0,0100 = 0,25
0,0101 = 0,3125
0,0110 = 0,375
0,0111 = 0,4375
0,1000 = 0,5
0,1001 = 0,5625
...
0,1111 = 0,9375
1,0000 = 1
Parmi les neuf valeurs décimales 0,1 ; 0,2 ; ... ; 0,9 seule 0,5 est
représentable exactement en binaire (c'est 0,1000) et toutes les
autres sont approchées. Par exemple, 0,1 en décimal est approchée au
mieux par 0,0010 en binaire qui vaut en réalité 0,125 en décimal :
0,0 <-> 0,0000 = 0
0,1 <-> 0,0010 = 0,125
0,2 <-> 0,0011 = 0,1875
0,3 <-> 0,0101 = 0,3125
0,4 <-> 0,0110 = 0,375
...
Regardons maintenant ce qui se passe quand on multiplie par 3 la
représentation binaire de 0,1 (0,0010 binaire qui vaut en réalité
0,125 en décimal). Le résultat est 0,0110 en binaire qui est la
représentation binaire de 0,4 en décimal (en réalité 0,375).
À cause des différences de représentations, on pourrait croire
que 3 × 0,1 = 0,4 alors que c'est seulement 3 × 0,125 = 0,375.
Il n'y a que Javascript à faire le gag, ou je me trompe ?

Pas du tout. Ce « gag » comme tu dis concerne tous les systèmes de
représentation des nombres dans une base (ici la base 2) suffisamment
différente de celle d'affichage (en l'occurrence la base 10). Si tu
ne vois pas ce gag dans d'autres langages, par exemple en C, c'est
qu'ils arrondissent le résultat à quelques chiffres seulement avant
l'affichage.
Exemple en C, avec un affichage de 0,1 avec 6 chiffres après la
virgule, puis avec 50 chiffres après la virgule :
printf("%.6fn", 0.1);
-> 0.100000
printf("%.50fn", 0.1);
-> 0.10000000000000000555111512312578270211815834045410
Je m'étais dit que j'allais consacrer une demi-journée à comprendre
comment se bidouille cette affaire, mais ... il faut une demi-journée
disponible :)

Si tu n'as pas le temps de comprendre ce qui se passe, alors au moins
retiens une chose : c'est qu'il ne faut pas faire de calculs avec des
nombres décimaux si tu peux les faire avec des nombres entiers -- cf.
mon exemple des euros et des centimes.
--
Olivier Miakinen
Avatar
Gloops
Le 22/08/2016 à 22:58, Olivier Miakinen a écrit :
Le 22/08/2016 20:16, Gloops a écrit :
Je m'étais figuré que 0.1 + 0.2 était la blague potache des créateurs de
Javascript, et que pour le reste ils allaient se tenir à carreau.

Ce n'est pas une blague, c'est juste le prix à payer quand on utilise
des nombres décimaux représentés sous forme binaire (représentation
IEEE754 sur 64 bits dans le cas de JavaScript).
[...]

Donc, on commet une erreur d'arrondi à la fin parce que la
représentation n'en a pas :)

Euh... non. Ou alors je n'ai pas compris ce que tu veux dire.
Prenons un autre exemple plus simple, en supposant que la représentation
binaire a exactement 4 bits après la virgule (ce n'est pas comme ça que
fonctionne la norme IEEE754 mais on retrouvera le même problème).
Le premier bit après la virgule vaut 1/2 soit 0,5. Le second bit vaut
1/4 soit 0,25. Le troisième vaut 0,125 et le quatrième 0,0625. Du coup
les valeurs possibles entre 0 et 1 sont les suivantes :
binaire = décimal
0,0000 = 0
0,0001 = 0,0625
0,0010 = 0,125
0,0011 = 0,1875
0,0100 = 0,25
0,0101 = 0,3125
0,0110 = 0,375
0,0111 = 0,4375
0,1000 = 0,5
0,1001 = 0,5625
...
0,1111 = 0,9375
1,0000 = 1
Parmi les neuf valeurs décimales 0,1 ; 0,2 ; ... ; 0,9 seule 0,5 est
représentable exactement en binaire (c'est 0,1000) et toutes les
autres sont approchées. Par exemple, 0,1 en décimal est approchée au
mieux par 0,0010 en binaire qui vaut en réalité 0,125 en décimal :
0,0 <-> 0,0000 = 0
0,1 <-> 0,0010 = 0,125
0,2 <-> 0,0011 = 0,1875
0,3 <-> 0,0101 = 0,3125
0,4 <-> 0,0110 = 0,375
...
Regardons maintenant ce qui se passe quand on multiplie par 3 la
représentation binaire de 0,1 (0,0010 binaire qui vaut en réalité
0,125 en décimal). Le résultat est 0,0110 en binaire qui est la
représentation binaire de 0,4 en décimal (en réalité 0,375).
À cause des différences de représentations, on pourrait croire
que 3 × 0,1 = 0,4 alors que c'est seulement 3 × 0,125 = 0,375.
Il n'y a que Javascript à faire le gag, ou je me trompe ?

Pas du tout. Ce « gag » comme tu dis concerne tous les systèmes de
représentation des nombres dans une base (ici la base 2) suffisamment
différente de celle d'affichage (en l'occurrence la base 10). Si tu
ne vois pas ce gag dans d'autres langages, par exemple en C, c'est
qu'ils arrondissent le résultat à quelques chiffres seulement avant
l'affichage.
Exemple en C, avec un affichage de 0,1 avec 6 chiffres après la
virgule, puis avec 50 chiffres après la virgule :
printf("%.6fn", 0.1);
-> 0.100000
printf("%.50fn", 0.1);
-> 0.10000000000000000555111512312578270211815834045410
Je m'étais dit que j'allais consacrer une demi-journée à comprendre
comment se bidouille cette affaire, mais ... il faut une demi-journée
disponible :)

Si tu n'as pas le temps de comprendre ce qui se passe, alors au moins
retiens une chose : c'est qu'il ne faut pas faire de calculs avec des
nombres décimaux si tu peux les faire avec des nombres entiers -- cf.
mon exemple des euros et des centimes.

Ah, il faut avouer que quand c'est bien expliqué ça va beaucoup plus vite :)