Bonjour, j’ai un script php qui génère un id aléatoirement, et lorsque je l’utilise en javascript, il me modifie ma variable ! Voici le problème :
Pièce jointe 364535Code:
1
2
3 id = 2603201817117452020446 alert(id)
Pourquoi ?
Cordialement,
Simon.
Version imprimable
Bonjour, j’ai un script php qui génère un id aléatoirement, et lorsque je l’utilise en javascript, il me modifie ma variable ! Voici le problème :
Pièce jointe 364535Code:
1
2
3 id = 2603201817117452020446 alert(id)
Pourquoi ?
Cordialement,
Simon.
c'est un float ...
il n'est pas modifié, il est juste écrit autrement
Merci beaucoup pour ta réponse, mais, comment faire pour qu’il ne soit pas remis autrement ?
Code:
1
2 var id = 2603201817117452020446; alert((id).toPrecision(22) );
@psychadelic, ton code ne fonctionne malheuresement pas.
Merci tout de même ;)
J'ai essayé chez moi sur FireFox et Chrome, ça marche parfaitement. :?
Et bien moi, j’ai copié collé ton code, et l’alert ne fonctionne pas
Pièce jointe 364589
Chez toi ça fonctionne ? https://simon511000.fr/testjs/index.html
C’est un problème commun à JavaScript et d’autres langages qui utilisent la norme IEEE 754. Tu trouveras plus d’explications sur la page MAX_SAFE_INTEGER du MDN.
Code:
1
2 var id = 2603201817117452020446; console.log(Number.isSafeInteger(id)); // false
Merci beaucoup Watilin, je comprend mieux.
Il y a moyen de passer outre cette limitation ?
oui, ça fonctionne parfaitement : Pièce jointe 364613
et comme l'a fait remarquer Watilin le chiffre à perdu de sa précision.
Ce qui est normal, JavaScript conserve les valeurs trop grandes via une notation par valeur exponentielles ce qui leur enlève de la précision.
Ce n'est pas un langage pour mathématiciens ou comptables, c'est un langage pour pages web.
Ce ci dit, il existe peut-être une librairie JS qui gère ce genre de besoin, qui sait ??
Ah si : http://mikemcl.github.io/decimal.js/
ou http://numeraljs.com/ si on à pas besoin de faire des calculs
Merci pour tes liens mais je n’arrive pas du tout à les utiliser.
En fait, j’ai l’impression que c’est des gigantesques librairies de mathématiques, alors que moi je veux juste avoir un grand id dans une variable.
Pourquoi javascrit a cette limitation est non php ?
Je ne comprend pas :(
Même problème avec PHP : http://php.net/manual/fr/language.types.float.php
Et c’est facile de vérifier par soi-même :
Ce script m’affiche float 2.6032018171175E+21. On observe bien la conversion en flottant et la perte de précision.Code:
1
2
3 <?php $unsafe = 2603201817117452020446; var_dump($unsafe);
Si tu as simplement besoin de comparer des id, tu peux les manipuler sous forme de chaînes. Les opérateurs > et < permettent aussi de comparer des chaînes, et la comparaison se fait sur l’ordre des codes ASCII des caractères. Par chance les codes ASCII des caractères "0" à "9" sont dans le même ordre que les chiffres correspondants :)
Par contre attention au piège : si tes chaînes sont de longueurs différentes, il faudra remplir la plus courte avec des zéros à gauche, sinon la comparaison ne sera pas bonne.
Code:
1
2
3 console.log("8" > "5"); // true console.log("8" > "53"); // true console.log("08" > "53"); // false
Bonjour,
je me trompe peut-être, mais je le passerais en chaine de caractères :
Ça ne risque plus de changer !Code:id = '2603201817117452020446';
Et si nécessaire, on utilise Number en cas de calcul ou autre.
Non ?
Ben déjà, si c'est juste pour que ce un id, qui est habituellement le terme utilisé pour désigner un identifiant, il est conseillé d'utiliser, et mieux de choisir un type Sting et non un type numérique.
Et s'il ne s'agit pas d'un identifiant, choisir un autre nom, parce que le terme id est utilisé partout sur les pages html, et choisir un tel terme est le meilleur moyen pour semer la confusion dans la compréhension de ton code.
Sinoon, la problématique de la précision numérique est une vieille antienne en informatique.
Les microprocesseurs sont maintenant sur 64 bits, c'est à dire qu'ils ne savent utiliser au mieux des nombres entre - 263 -1 et + 263 -1.
le 64eme bit est utilisé pour le signe positif ou négatif ( et le -1 parce qu'on part de zéro)
ce qui représente en format exponentiel +- 9,22337203685e+18
on est déjà au delà de cette valeur avec ton chiffre dont l’exponentiel est de 21, ce qui signifie que ton chiffre ne rentre pas dans une représentation binaire et directe sur 64 bits.
La norme dont parle Watilin : IEEE 754 utilise une mantisse de 52 bits, soit -+252 -1 (=9,00719925474e+15), les 11 bits manquant sont eux utilisés pour indiquer la valeur de l'exposant, de 0 à 211 -1 soit de zéro a 2047.
Au résultat, tant que tu manipule des chiffres utilisant moins de 52bits, leur représentation sera précise, d'ou le test proposé par Watilin ( Number.isSafeInteger(id) ).
Si tu dépasse ne serait-d'un point, alors leur représentation passe en format exponentiel, et il ne sont plus que des estimations de grandeur.
Les premiers calculateurs étaient loin d'avoir les 64 bits qu'on connaît aujourd'hui, et il a bien fallut développer les premières librairies de calculs.
Dans le cas de JavaScript, cette norme est largement suffisante pour couvrir 99% des calculs utiles que l'on peut rencontrer pour faire des pages internet. et en cas de besoin il y a la librairie JavaScript que je t'ai indiqué ( decimal.js).
Ah oui, je ne savais pas qu’il y avait ce problème en php.
Ouiii, ça fonctionne maintenant, il fallait y penser à mettre l’id en string !
Oui, j’ai peut-être un peu exagérer :
mais je ne voulais pas que 2 utilisateurs aient la même id, ça ferai tout plenter.Code:
1
2 $donnees["id"] = "".date(dmYHIs)."".mt_rand(1,999999999)."";
oui tu as 100% raison.
Grace à vous, j’ai mis mon id en string et ça fonctionne :
Pièce jointe 364724
Je ne vous remercirai jamais assez :D