[ Web Proxy ]
URL:
Viewing: https://fr.javascript.info/number [Back]  [Original]

Nombres
FR

Nous souhaitons rendre ce projet open source disponible pour les gens du monde entier.

Aidez-nous traduire le contenu de ce tutoriel dans votre langue!

    Rechercher sur Javascript.info:
    Rechercher dans le tutoriel:
    Light themeDark theme
    DanskEnglishEspaolFranaisIndonesiaItalianoTrkeOzbek

    En JavaScript moderne, il existe deux types de nombres :

    1. Les nombres standards en JavaScript sont stocks au format 64 bits IEEE-754, galement connu sous le nom de nombres virgule flottante double prcision. Ce sont des chiffres que nous utilisons le plus souvent, et nous en parlerons dans ce chapitre.

    2. Les nombres BigInt pour reprsenter des entiers de longueur arbitraire. Ils sont parfois ncessaires, car un nombre rgulier ne peut pas dpasser de manire prcise 253 ou tre infrieur -253. Comme les bigints sont utiliss dans quelques zones spciales, nous leur consacrons un chapitre spcial BigInt.

    Nous allons donc parler ici des nombres rguliers. Dveloppons nos connaissances leur sujet.

    Plus de faons dcrire un nombre

    Imaginez que nous ayons besoin dcrire 1 milliard. Le moyen vident est :

    let milliard = 1000000000;

    Nous pouvons galement utiliser lunderscore _ comme sparateur :

    let billion = 1_000_000_000;

    Ici, lunderscore _ joue le rle de sucre syntaxique, il rend le nombre plus lisible. Le moteur JavaScript ignore simplement _ entre les chiffres, donc cest exactement le mme milliard que ci-dessus.

    Dans la vraie vie cependant, nous essayons dviter dcrire de longues squences de zros. Nous sommes trop paresseux pour a. Nous essaierons dcrire quelque chose comme 1 milliard pour un milliard ou 7,3 milliards pour 7 milliards 300 millions. La mme chose est vraie pour la plupart des grands nombres.

    En JavaScript, nous pouvons raccourcir un nombre en y ajoutant la lettre "e" et en spcifiant le nombre de zros :

    let milliard = 1e9;  // 1 milliard, littralement : 1 suivi de 9 zros
    
    alert( 7.3e9 );  // 7.3 milliards (pareil que 7300000000 ou 7_300_000_000)

    En dautres termes, e multiplie le nombre par 1 suivi du nombre de zros spcifi.

    1e3 === 1 * 1000 // e3 signifie *1000
    1.23e6 === 1.23 * 1000000 // e6 signifie *1000000

    Maintenant, crivons quelque chose de trs petit. Disons, 1 microseconde (un millionime de seconde) :

    let us = 0.000001;

    Comme avant, lutilisation de "e" peut nous aider. Si nous voulons viter dcrire les zros explicitement, nous pourrions dire la mme chose comme :

    let us = 1e-6; // cinq zros  gauche de 1

    Si nous comptons les zros dans 0.000001, il y en a 6. Donc logiquement, cest 1e-6.

    En dautres termes, un nombre ngatif aprs "e" signifie une division par 1 suivi du nombre spcifi de zros :

    // -3 divise par 1 avec 3 zros
    1e-3 === 1 / 1000; // 0.001
    
    // -6 divise par 1 avec 6 zros
    1.23e-6 === 1.23 / 1000000; // 0.00000123
    
    // an example with a bigger number
    1234e-2 === 1234 / 100; // 12.34, decimal point moves 2 times

    Nombres hexadcimaux, binaires et octaux

    Les nombres Hexadcimaux sont souvent utiliss en JavaScript pour reprsenter des couleurs, encoder des caractres et pour beaucoup dautres choses. Alors, naturellement, il existe un moyen plus court de les crire : 0x puis le nombre.

    Par exemple :

    alert( 0xff ); // 255
    alert( 0xFF ); // 255 (mme rsultat car la casse n'a pas d'importance)

    Les systmes numriques binaires et octaux sont rarement utiliss, mais sont galement supports avec les prfixes 0b et 0o :

    let a = 0b11111111; // forme binaire de 255
    let b = 0o377; // forme octale de 255
    
    alert( a == b ); // true, car a et b valent le mme nombre, soit 255

    Cependant a ne fonctionne quavec ces 3 systmes de numration. Pour les autres systmes numrique, nous devrions utiliser la fonction parseInt (que nous verrons plus loin dans ce chapitre).

    La mthode toString(base)

    La mthode num.toString(base) retourne une chane de caractres reprsentant num dans le systme numrique de la base donne.

    Par exemple :

    let num = 255;
    
    alert( num.toString(16) ); // ff
    alert( num.toString(2) );  // 11111111

    La base peut varier de 2 36. Par dfaut, il sagit de 10.

    Les cas dutilisation courants sont :

    • base=16 est utilis pour les couleurs hexadcimales, les encodages de caractres, etc. Les chiffres peuvent tre 0..9 ou A..F.

    • base=2 est principalement utilis pour le dbogage doprations binaires, les chiffres pouvant tre 0 ou 1.

    • base=36 est le maximum, les chiffres peuvent tre 0..9 ou A..Z. Lalphabet latin entier est utilis pour reprsenter un nombre. Un cas amusant mais utile pour la base 36 consiste transformer un identifiant numrique long en quelque chose de plus court, par exemple pour crer une URL courte. On peut simplement le reprsenter dans le systme numrique avec base 36 :

      alert( 123456..toString(36) ); // 2n9c
    Deux points pour appeler une mthode

    Veuillez noter que deux points sur 123456..toString(36) nest pas une faute de frappe. Si nous voulons appeler une mthode directement sur un nombre, comme toString dans lexemple ci-dessus, nous devons placer deux points .. avant la mthode.

    Si nous plaions un seul point : 123456.toString(36), il y aurait une erreur, car la syntaxe JavaScript applique la partie dcimale aprs le premier point et il lirait toString(36) comme tant la partie dcimale de 123456 ce qui nest pas le cas. Si nous plaons un point de plus, alors JavaScript sait que la partie dcimale est vide et peut maintenant appliquer la mthode.

    Il est aussi possible dcrire (123456).toString(36).

    Arrondir

    Arrondir est lune des oprations les plus utilises pour travailler avec des nombres.

    Il existe plusieurs fonctions intgres pour arrondir :

    Math.floor
    Arrondis vers le bas : 3.1 devient 3, et -1.1 devient -2.
    Math.ceil
    Arrondis ver le haut : 3.1 devient 4, et -1.1 devient -1.
    Math.round
    Arrondit lentier le plus proche : 3,1 devient 3, 3,6 devient 4 et pour le cas du milieu, 3,5 est galement arrondit 4.
    Math.trunc (non pris en charge par Internet Explorer)
    Supprime tout ce qui suit le point dcimal : 3.1 devient 3, -1.1 devient -1.

    Voici le tableau pour rsumer les diffrences entre eux :

    Math.floor Math.ceil Math.round Math.trunc
    3.1 3 4 3 3
    3.6 3 4 4 3
    -1.1 -2 -1 -1 -1
    -1.6 -2 -1 -2 -1

    Ces fonctions couvrent toutes les manires possibles de traiter la partie dcimale dun nombre. Mais que se passe-t-il si nous voulons arrondir le nombre un certain chiffre aprs la virgule ?

    Par exemple, nous avons 1.2345 et voulons larrondir 2 chiffres, pour obtenir seulement 1.23.

    Il y a deux faons de le faire:

    1. Multiplier et diviser.

      Par exemple, pour arrondir le nombre au 2me chiffre aprs la dcimale, nous pouvons multiplier le nombre par 100, appeler la fonction darrondi puis le diviser.

      let num = 1.23456;
      
      alert( Math.round(num * 100) / 100 ); // 1.23456 -> 123.456 -> 123 -> 1.23
    2. La mthode toFixed(n) arrondit le nombre n chiffres aprs le point et renvoie une chane de caractres du rsultat.

      let num = 12.34;
      alert( num.toFixed(1) ); // "12.3"

      Ceci arrondit la valeur la plus proche, similaire Math.round :

      let num = 12.36;
      alert( num.toFixed(1) ); // "12.4"

      Veuillez noter que le rsultat de toFixed est une chane de caractres. Si la partie dcimale est plus courte quindique, des zros sont ajouts la fin :

      let num = 12.34;
      alert( num.toFixed(5) ); // "12.34000", ajout de zros pour faire exactement 5 chiffres

      Nous pouvons le convertir en un nombre en utilisant le plus unaire + ou un appel Number() : +num.toFixed(5).

    Calculs imprcis

    En interne, un nombre est reprsent au format 64 bits IEEE-754, il y a donc exactement 64 bits pour stocker un nombre : 52 dentre eux sont utiliss pour stocker les chiffres, 11 dentre eux stockent la position du point dcimal (ils sont zro pour les nombres entiers), et 1 bit est pour le signe.

    Si un nombre est vraiment norme, il peut dborder du stockage 64 bits et devenir une valeur numrique spciale Infinity :

    alert( 1e500 ); // infini

    Ce qui est peut-tre un peu moins vident, mais qui arrive souvent, est la perte de prcision.

    Considrez ce (faux !) test dgalit :

    alert( 0.1 + 0.2 == 0.3 ); // faux

    Si on vrifie si la somme de 0.1 et 0.2 est gale 0.3 on obtient faux.

    trange ! Quest-ce que cest alors si ce nest pas 0.3?

    alert( 0.1 + 0.2 ); // 0.30000000000000004

    Aie ! Imaginez que vous criez un site de-commerce et que le visiteur mette des produits 0,10 et 0,20 dans son panier. Le total de la commande sera de 0,30000000000000004 . Cela surprendrait nimporte qui.

    Mais pourquoi cela se produit-il ?

    Un nombre est stock en mmoire sous sa forme binaire, une squence de uns et de zros. Mais les fractions telles que 0.1, 0.2, qui semblent simples dans le systme numrique dcimal, sont en ralit des fractions sans fin dans leur forme binaire.

    En dautres termes, quest-ce que 0.1 ? Cest un divis par dix 1/10, un dixime. Dans le systme numrique dcimal, ces nombres sont facilement reprsentables. Comparez-le un tiers : 1/3. Cela devient une fraction sans fin 0.33333(3).

    Ainsi, la division par puissances 10 est garantie de bien fonctionner dans le systme dcimal, mais la division par 3 ne lest pas. Pour la mme raison, dans le systme de numration binaire, la division par des puissances de 2 est garantie, mais 1/10 devient une fraction binaire sans fin.

    Il nexiste aucun moyen de stocker exactement 0.1 ou exactement 0.2 laide du systme binaire, tout comme il nexiste aucun moyen de stocker un tiers sous forme de fraction dcimale.

    Le format numrique IEEE-754 rsout ce problme en arrondissant au nombre le plus proche possible. Ces rgles darrondissement ne nous permettent normalement pas de voir cette petite perte de prcision, mais elle existe.

    Nous pouvons voir cela en action :

    alert( 0.1.toFixed(20) ); // 0.10000000000000000555

    Et quand on additionne deux nombres, leurs pertes de prcision sadditionnent.

    Cest pourquoi 0.1 + 0.2 nest pas exactement 0.3.

    Pas seulement JavaScript

    Le mme problme existe dans de nombreux autres langages de programmation.

    PHP, Java, C, Perl, Ruby donnent exactement le mme rsultat, car ils sont bass sur le mme format numrique.

    Pouvons-nous contourner le problme ? Bien sr, la mthode la plus fiable est darrondir le rsultat laide dune mthode toFixed(n):

    let sum = 0.1 + 0.2;
    alert( sum.toFixed(2) ); // "0.30"

    Veuillez noter que toFixed renvoie toujours une chane de caractres. Il sassure quil a 2 chiffres aprs le point dcimal. Cest pratique si nous avons un magasin en ligne et devons montrer 0.30$. Pour les autres cas, nous pouvons utiliser le plus unaire + pour le contraindre en un nombre :

    let sum = 0.1 + 0.2;
    alert( +sum.toFixed(2) ); // 0.3

    Nous pouvons galement multiplier temporairement les nombres par 100 (ou un nombre plus grand) pour les transformer en nombres entiers, faire le calcul, puis rediviser. Ensuite, comme nous faisons des calculs avec des nombres entiers, lerreur diminue quelque peu, mais nous lobtenons toujours sur la division:

    alert( (0.1 * 10 + 0.2 * 10) / 10 ); // 0.3
    alert( (0.28 * 100 + 0.14 * 100) / 100); // 0.4200000000000001

    Ainsi, lapproche multiplier/diviser rduit lerreur, mais ne la supprime pas totalement.

    Parfois, nous pourrions essayer dviter les fractions compltement. Par exemple, si nous traitons avec un magasin, nous pouvons stocker les prix en cents au lieu de dollars. Mais que se passe-t-il si nous appliquons une rduction de 30%? En pratique, il est rarement possible dviter totalement les fractions. Il suffit de les arrondir pour couper les queues si ncessaire.

    La chose amusante

    Essayez de lancer ceci :

    // Bonjour! Je suis un nombre auto-croissant!
    alert( 9999999999999999 ); // affiche 10000000000000000

    La cause est encore une fois le manque de prcision. Le nombre comporte 64 bits, dont 52 peuvent tre utiliss pour stocker des chiffres, mais cela ne suffit pas. Alors, les chiffres les moins significatifs disparaissent.

    JavaScript ne dclenche pas derreur dans de tels vnements. il fait de son mieux pour adapter le nombre au format souhait, mais malheureusement, ce format nest pas assez grand.

    Deux zros

    Une autre consquence amusante de la reprsentation interne des nombres est lexistence de deux zros : 0 et -0.

    Cest parce que le signe est reprsent par un bit, il peut donc tre dfini ou non pour nimporte quel nombre, y compris le zro.

    Dans le plupart des cas, la distinction est imperceptible, car les oprateurs peuvent les traiter de la mme manire.

    Tests : isFinite et isNaN

    Vous rappelez-vous de ces deux valeurs numriques spciales ?

    • Infinite (et -Infinite) sont des valeurs numriques spciales qui sont suprieures (infrieure) tout.
    • NaN reprsente une erreur.

    Ils appartiennent au type number, mais ne sont pas des numros normaux. Il existe donc des fonctions spciales pour les vrifier :

    • isNaN(valeur) convertit son argument en un nombre et teste ensuite sil est NaN :

      alert( isNaN(NaN) ); // true
      alert( isNaN("str") ); // true

      Mais avons-nous besoin de cette fonction ? Ne pouvons-nous pas simplement utiliser la comparaison === NaN ? Malheureusement non. La valeur NaN est unique en ce sens quelle ne vaut rien, y compris elle-mme :

      alert( NaN === NaN ); // false
    • isFinite(valeur) convertit son argument en un nombre et renvoie true sil sagit dun nombre rgulier, pas de NaN / Infinity / -Infinity :

      alert( isFinite("15") ); // true
      alert( isFinite("str") ); // false, car c'est une valeur non rgulire: NaN
      alert( isFinite(Infinity) ); // false, car c'est aussi une valeur non rgulire: Infinity

    Parfois, isFinite est utilis pour valider si une valeur de chane de caractres est un nombre rgulier :

    let num = +prompt("Entrez un nombre", '');
    
    // sera vrai, sauf si vous entrez Infinity, -Infinity ou NaN
    alert( isFinite(num) );

    Veuillez noter quune chane de caractres vide ou une chane de caractres contenant seulement des espaces est traite comme 0 dans toutes les fonctions numrique, y compris isFinite.

    Number.isNaN et Number.isFinite

    Les mthodes Number.isNaN et Number.isFinite sont des versions plus strictes des fonctions isNaN et isFinite. Elles ne convertissent pas automatiquement leur argument en nombre, mais vrifient sil appartient au type number.

    • Number.isNaN(value) retourne true si largument appartient au type number et sil vaut NaN. Dans tous les autres cas, elle retourne false.

      alert( Number.isNaN(NaN) ); // true
      alert( Number.isNaN("str" / 2) ); // true
      
      // Notez la diffrence :
      alert( Number.isNaN("str") ); // false, car "str" est de type "string"
      alert( isNaN("str") ); // true, car isNaN convertit la string "str" en un nombre et obtient NaN comme rsultatde la conversion
    • Number.isFinite(value) retourne true si largument appartient au type number et sil vaut ni NaN, ni Infinity, ni -Infinity. Dans tous les autres cas, elle retourne false.

      alert( Number.isFinite(123) ); // true
      alert( Number.isFinite(Infinity) ); // false
      alert( Number.isFinite(2 / 0) ); // false
      
      // Notez la diffrence :
      alert( Number.isFinite("123") ); // false, car "123" est de type "string"
      alert( isFinite("123") ); // true, car isFinite convertit la string "123" en un nombre 123

    En quelque sorte, les fonction Number.isNaN et Number.isFinite sont plus simples et plus directes que les fonctions isNaN et isFinite. Cependant, en pratique isNaN et isFinite sont plus souvent utilises car elles sont plus courtes crire.

    Comparer avec Object.is

    Il existe une mthode intgre spciale Object.is qui compare des valeurs telles que ===, mais qui est plus fiable pour deux cas extrmes :

    1. Cela fonctionne avec NaN : Object.is(NaN, NaN) === true, cest une bonne chose.
    2. Les valeurs 0 et -0 sont diffrentes : Object.is(0, -0) === false, techniquement cest vrai, car le numro a en interne un bit de signe qui peut tre diffrent mme si tous les autres bits sont zro.

    Dans tous les autres cas, Object.is(a, b) est identique a === b.

    Nous mentionnons Object.is ici, car il est souvent utilis dans les spcifications JavaScript. Lorsquun algorithme interne doit comparer deux valeurs pour tre exactement identiques, il utilise Object.is (appel en interne SameValue).

    parseInt et parseFloat

    La conversion numrique laide dun plus + ou Number() est strict. Si une valeur nest pas exactement un nombre, elle choue :

    alert( +"100px" ); // NaN

    La seule exception concerne les espaces au dbut ou la fin de la chane de caractres, car ils sont ignors.

    Mais dans la vraie vie, nous avons souvent des valeurs en units, comme "100px" ou "12pt" en CSS. En outre, dans de nombreux pays, le symbole montaire se situe aprs le montant. Nous avons donc "19" et souhaitons en extraire une valeur numrique.

    Cest quoi servent parseInt et parseFloat.

    Ils lisent un nombre dune chane jusqu ce quils ne puissent plus. En cas derreur, le numro rassembl est renvoy. La fonction parseInt renvoie un entier, tandis que parseFloat renvoie un nombre virgule :

    alert( parseInt('100px') ); // 100
    alert( parseFloat('12.5em') ); // 12.5
    
    alert( parseInt('12.3') ); // 12, seule la partie entire est renvoye
    alert( parseFloat('12.3.4') ); // 12.3, le deuxime point arrte la lecture

    Il y a des situations o parseInt / parseFloat retournera NaN. Cela arrive quand on ne peut lire aucun chiffre :

    alert( parseInt('a123') ); // NaN, le premier symbole arrte le processus
    Le second argument de parseInt(str, radix)

    La fonction parseInt() a un second paramtre optionnel. Il spcifie la base du systme numrique, ce qui permet parseInt danalyser galement les chanes de nombres hexadcimaux, binaires, etc. :

    alert( parseInt('0xff', 16) ); // 255
    alert( parseInt('ff', 16) ); // 255, sans 0x cela fonctionne galement
    
    alert( parseInt('2n9c', 36) ); // 123456

    Autres fonctions mathmatiques

    JavaScript a un objet Math intgr qui contient une petite bibliothque de fonctions et de constantes mathmatiques.

    Quelques exemples :

    Math.random()

    Retourne un nombre alatoire de 0 1 (1 non compris).

    alert( Math.random() ); // 0.1234567894322
    alert( Math.random() ); // 0.5435252343232
    alert( Math.random() ); // ... (tout nombre alatoire)
    Math.max(a, b, c...) et Math.min(a, b, c...)

    Renvoie le plus grand et le plus petit dun nombre arbitraire darguments.

    alert( Math.max(3, 5, -10, 0, 1) ); // 5
    alert( Math.min(1, 2) ); // 1
    Math.pow(n, power)

    Renvoie n lev la puissance power donne.

    alert( Math.pow(2, 10) ); // 2 puissance 10 = 1024

    Il y a plus de fonctions et de constantes dans lobjet Math, y compris la trigonomtrie, que vous pouvez trouver dans la documentation de lobjet Math.

    Rsum

    Pour crire des nombres avec beaucoup de zros :

    • Ajoutez "e" avec le nombre de zros au nombre. Comme 123e6 est 123 avec 6 zros soit 123000000.
    • Un nombre ngatif aprs le "e" entrane la division du nombre par 1 suivi par le nombre de zros donns. Comme 123-e6 est 123 divis par 1 suivi de 6 zros, soit 0.000123 (123 millionimes).

    Pour diffrents systmes de numration :

    • Il est possible dcrire des nombres directement dans les systmes hex (0x), octal (0o) et binaire (0b).
    • parseInt(str, base) passe la chane de caractres str vers un systme numrique avec une base donne : 2 base 36.
    • num.toString(base) convertit un nombre en chane de caractres dans le systme numrique de la base donne.

    Pour les tests de nombres rguliers:

    • isNaN(value) convertit son argument en nombre puis vrifie sil sagit de NaN.
    • Number.isNaN(value) vrifie si son argument appartient au type number et, si cest le cas, vrifie sil sagit de NaN.
    • isFinite(value) convertit son argument en nombre puis vrifie sil ne sagit pas de NaN / Infinity / -Infinity.
    • Number.isFinite(value) vrifie si son argument appartient au type number et, si cest le cas, vrifie sil ne sagit pas de NaN / Infinity / -Infinity.

    Pour convertir des valeurs telles que 12pt et 100px en nombres :

    • Utiliser parseInt / parseFloat pour la conversion soft, qui lit un nombre partir dune chane de caractres, puis renvoie la valeur quil pouvait lire avant de rencontrer une erreur.

    Pour les fractions :

    • Arrondissez en utilisant Math.floor, Math.ceil, Math.trunc, Math.round ou num.toFixed(prcision).
    • Assurez-vous de ne pas perdre de prcision lorsque vous travaillez avec des fractions.

    Plus de fonctions mathmatiques :

    • Voir lobjet Math quand vous en avez besoin. La bibliothque est trs petite, mais peut couvrir les besoins de base.

    Exercices

    importance: 5

    Crez un script qui invite le visiteur entrer deux nombres, puis affiche leur somme.

    [Lancer la dmo]

    P.S. Il y a un pige avec les types.

    solution
    let a = +prompt("Le premier numro?", "");
    let b = +prompt("Le second numro?", "");
    
    alert( a + b );

    Notez le plus unaire + avant le prompt. Il convertit immdiatement la valeur en nombre.

    Sinon, a et b seraient des string et leur somme serait leur concatnation, cest dire: "1" + "2" = "12".

    importance: 4

    Selon la documentation, Math.round et toFixed arrondissent tous les deux au nombre le plus proche : 0..4 arrondi par dfaut ( la baisse) tantdis que 5..9 arrondi par excs ( la hausse).

    Par exemple :

    alert( 1.35.toFixed(1) ); // 1.4

    Dans lexemple similaire ci-dessous, pourquoi est-ce que 6.35 est arrondi 6.3 et non 6.4 ?

    alert( 6.35.toFixed(1) ); // 6.3

    Comment arrondir 6.35 de la bonne manire ?

    solution

    En interne, la fraction dcimale 6.35 est un nombre binaire sans fin. Comme toujours dans de tels cas, il est stock avec une perte de prcision.

    Voyons cela :

    alert( 6.35.toFixed(20) ); // 6.34999999999999964473

    La perte de prcision peut causer la fois une augmentation et une diminution dun nombre. Dans ce cas particulier, le nombre diminue un peu, cest pourquoi il a t arrondi 6.3.

    Et quand est-il de 1.35 ?

    alert( 1.35.toFixed(20) ); // 1.35000000000000008882

    Ici, la perte de prcision rend le nombre un peu plus grand, cest pourquoi il a t arrondi 1.4.

    Comment pouvons-nous rsoudre le problme avec 6.35 si nous voulons quil soit arrondi correctement ?

    Nous devons le rapprocher dun nombre entier avant darrondir :

    alert( (6.35 * 10).toFixed(20) ); // 63.50000000000000000000

    Notez que 63.5 na aucune perte de prcision. Cest parce que la partie dcimale 0.5 est en ralit 1/2. Les fractions divises par les puissances de 2 sont reprsentes sans perte de prcision dans le systme binaire, on peut maintenant les arrondir :

    alert( Math.round(6.35 * 10) / 10); // 6.35 -> 63.5 -> 64(arrondi) -> 6.4
    importance: 5

    Crez une fonction readNumber qui invite entrer un nombre jusqu ce que le visiteur saisisse une valeur numrique valide.

    La valeur rsultante doit tre renvoye sous forme de nombre.

    Le visiteur peut galement arrter le processus en entrant une ligne vide ou en appuyant sur CANCEL. Dans ce cas, la fonction doit renvoyer null.

    [Lancer la dmo]

    Open a sandbox with tests.

    solution
    function readNumber() {
      let num;
    
      do {
        num = prompt("Entrez un nombre s'il vous plat", 0);
      } while ( !isFinite(num) );
    
      if (num === null || num === '') return null;
    
      return +num;
    }
    
    alert(`Read: ${readNumber()}`);

    La solution est un peu plus complexe quelle ny parat car nous devons grer des lignes null / vides.

    Nous rptons donc la demande jusqu ce quil sagisse dun nombre rgulier. Les lignes null (cancel) et vide rpondent galement cette condition car, sous forme numrique, elles valent 0.

    Aprs que nous nous sommes arrts, nous devons traiter spcialement les lignes null et vides (retourner null), car les convertir en nombre renverrait 0.

    Ouvrez la solution avec des tests dans une sandbox.

    importance: 4

    Cette boucle est infinie. a ne finit jamais. Pourquoi ?

    let i = 0;
    while (i != 10) {
      i += 0.2;
    }
    solution

    Cest parce que i ne sera jamais exactement gal 10.

    Excutez-le pour voir les valeurs relles de i :

    let i = 0;
    while (i < 11) {
      i += 0.2;
      if (i > 9.8 && i < 10.2) alert( i );
    }

    Aucun dentre eux nest exactement 10.

    De telles choses se produisent cause des pertes de prcision lors de lajout des fractions comme 0.2.

    Conclusion : vitez les contrles dgalit lorsque vous travaillez avec des fractions dcimales.

    importance: 2

    La fonction intgre Math.random() cre une valeur alatoire de 0 1 (1 non compris).

    Ecrivez la fonction random(min, max) pour gnrer un nombre alatoire compris entre min et max (max non compris).

    Quelques exemples :

    alert( random(1, 5) ); // 1.2345623452
    alert( random(1, 5) ); // 3.7894332423
    alert( random(1, 5) ); // 4.3435234525
    solution

    Nous devons mapper toutes les valeurs de lintervalle 01 en valeurs de min max.

    Cela peut tre fait en deux tapes :

    1. Si nous multiplions un nombre alatoire de 01 par max-min, lintervalle des valeurs possible augmente de 0..1 0..max-min.
    2. Maintenant, si nous ajoutons min, lintervalle possible devient de min max.

    La fonction :

    function random(min, max) {
      return min + Math.random() * (max - min);
    }
    
    alert( random(1, 5) );
    alert( random(1, 5) );
    alert( random(1, 5) );
    importance: 2

    Crez une fonction randomInteger(min, max) qui gnre un nombre entier alatoire compris entre min et max (min et max inclut).

    Tout nombre compris dans lintervalle min..max doit apparatre avec la mme probabilit.

    Quelques exemples :

    alert( randomInteger(1, 5) ); // 1
    alert( randomInteger(1, 5) ); // 3
    alert( randomInteger(1, 5) ); // 5

    Vous pouvez utiliser la solution de la tche prcdente comme base.

    solution
    La solution simple mais fausse

    La solution simple mais fausse

    La solution la plus simple mais fausse serait de gnrer une valeur de min max et de larrondir :

    function randomInteger(min, max) {
      let rand = min + Math.random() * (max - min);
      return Math.round(rand);
    }
    
    alert( randomInteger(1, 3) );

    La fonction marche, mais elle est incorrecte. La probabilit dobtenir les valeurs min et max est deux fois infrieure toute autre.

    Si vous excutez lexemple ci-dessous plusieurs fois, vous verrez facilement que 2 apparat le plus souvent.

    Cela se produit car Math.round() obtient des nombres alatoires partir de lintervalle 1..3 et les arrondit comme ici :

    values from 1    ... to 1.4999999999  devient 1
    values from 1.5  ... to 2.4999999999  devient 2
    values from 2.5  ... to 2.9999999999  devient 3

    Maintenant, nous pouvons clairement voir que 1 obtient deux fois moins de valeurs que 2. Et la mme chose avec 3.

    La bonne solution

    La bonne solution

    Il existe de nombreuses solutions correctes la tche. Lune delles consiste ajuster les limites dintervalle. Pour garantir les mmes intervalles, nous pouvons gnrer des valeurs comprises entre 0.5 et 3.5, ajoutant ainsi les probabilits requises :

    function randomInteger(min, max) {
      // maintenant rand est entre (min-0.5) et (max+0.5)
      let rand = min - 0.5 + Math.random() * (max - min + 1);
      return Math.round(rand);
    }
    
    alert( randomInteger(1, 3) );

    Une autre solution pourrait tre dutiliser Math.floor pour un nombre alatoie compris entre min et max+1.

    function randomInteger(min, max) {
      // ici rand est de min  (max+1)
      let rand = min + Math.random() * (max + 1 - min);
      return Math.floor(rand);
    }
    
    alert( randomInteger(1, 3) );

    Maintenant, tous les intervalles sont mapps de cette faon :

    values from 1  ... to 1.9999999999  devient 1
    values from 2  ... to 2.9999999999  devient 2
    values from 3  ... to 3.9999999999  devient 3

    Tous les intervalles ont la mme longueur, rendant la distribution finale uniforme.

    Carte du tutoriel

    Commentaires

    lire ceci avant de commenter
    • Si vous avez des amliorations suggrer, merci de soumettre une issue GitHub ou une pull request au lieu de commenter.
    • Si vous ne comprenez pas quelque chose dans l'article, merci de prciser.
    • Pour insrer quelques bouts de code, utilisez la balise <code>, pour plusieurs lignes enveloppez-les avec la balise <pre>, pour plus de 10 lignes - utilisez une sandbox (plnkr, jsbin, codepen)

    Web Proxy Viewer  |  New URL  |  Original Page