Les mathématiques.round(num) vs num.toFixed(0) et le navigateur incohérences
Considérons le code suivant:
for (var i=0;i<3;i++){
var num = i + 0.50;
var output = num + " " + Math.round(num) + " " + num.toFixed(0);
alert(output);
}
Dans Opera 9.63-je obtenir:
0.5 1 0
1.5 2 2
2.5 3 2
Dans FF 3.03-je obtenir:
0.5 1 1
1.5 2 2
2.5 3 3
Dans IE 7 j'obtiens:
0.5 1 0
1.5 2 2
2.5 3 3
Note le gras des résultats. Pourquoi sont-ce les incohérences présentes? Est-ce à dire que toFixed(0)
doit être évitée? Quel est le bon moyen pour arrondir un nombre à l'entier le plus proche?
- FWIW IE6 de sortie est identique à votre IE7 et FF2(.0.0.20) est identique à votre FF3, windows.
- Semble être fixé à l'Opéra de 10 maintenant.
- Commencez avec "i = -3" dans la boucle for, et ça devient de pire! Il y a beaucoup de mauvaises normes concernant l'arrondissement. Pour nous, les programmeurs de la meilleure mise en œuvre est arrondissement ".5" en vue de la prochaine même nombre (banquiers arrondissement), le pire est arrondissement ".5", ce qui est la norme de la "en Mathématiques.rond" et comme aujourd'hui, IE, Chrome et Opéra de la suivre. Quel est le problème avec elle? Regardez ceci: "(round(x*-1) + round(x))" n'entraîne pas nécessairement 0 plus. "num.toFixed" de tous ces navigateurs effectuer commerciale de l'arrondissement loin de 0 ce qui est correct pour les programmeurs et plus compréhensible pour les clients.
Vous devez vous connecter pour publier un commentaire.
Edit: pour répondre À vos modifier, utiliser
Math.round
. Vous pouvez également prototype de laNumber
objet de l'avoir faire votre volonté si vous préférez que la syntaxe.Je n'ai jamais utilisé
Number.toFixed()
avant (surtout parce que la plupart des bibliothèques JS fournir untoInt()
méthode), mais à en juger par vos résultats, je dirais qu'il serait plus cohérent d'utiliser leMath
méthodes (round
,floor
,ceil
) puistoFixed
si la croix-navigateur consistance est ce que vous cherchez.Math.round()
est près de 500% plus rapide que.toFixed
(jsperf.com/math-round-vs-tofixed2).Number
)?Je pense que FF est en train de faire la bonne chose avec toFixed, depuis l'étape 10 ci-dessous dit "Si il y a deux ans, de choisir le plus grand de n."
Et comme Subvention De Wagner dit: Utiliser Mathématiques.ceil(x) ou Mathématiques.floor(x) au lieu de x.toFixed().
Tout ce qui est ci-dessous à partir de la Spécification Du Langage ECMAScript:
Pour répondre à vos deux original des problèmes/questions:
Mathématiques.round(num) vs num.toFixed(0)
Le problème ici réside dans l'idée fausse que l'on devrait toujours donner le même résultat. Ils sont, en fait, régis par des règles différentes. Regardez les nombres négatifs, par exemple. Parce que
Math.ronde
utilise "arrondi au demi" comme la règle, vous verrez queMath.round(-1.5)
évalue à-1
même siMath.round(1.5)
évalue à2
.Number.prototype.toFixed
, d'autre part, utilise ce qui est essentiellement équivalent à "ronde de la moitié de l'écart de zéro" comme la règle, selon l'étape 6 de la spécification, qui dit essentiellement: pour traiter les négatifs comme des nombres positifs, puis ajouter le signe négatif à la fin. Ainsi,(-1.5).toFixed(0) === "-2"
et(1.5).toFixed(0) === "2"
sont exacts dans tous conformes aux spécifications des navigateurs. Notez que ces valeurs sont des chaînes de caractères, pas des numéros. A noter de plus que les deux-1.5.toFixed(0)
et-(1.5).toFixed(0)
sont=== -2
(le nombre) en raison de la priorité des opérateurs.Navigateur incohérences
La plupart des navigateurs modernes—
ou au moins ceux que vous pourrait s'attendre à un soutien à la rédaction de ce documentsauf pour IE—doit tout mettre en œuvre les spécifications correctement. (Selon Renee commentaire, letoFixed
question vous l'avez souligné dans l'Opéra a été résolu, probablement depuis qu'ils ont commencé à l'aide de la même JS moteur comme google Chrome.) Il est toujours bon de répéter que, même si les spécifications ont été mises en œuvre de manière cohérente sur tous les navigateurs, le comportement défini dans les spécifications, en particulier pour lestoFixed
arrondi, peut être encore un peu pas intuitif pour un "simple mortel" JS développeurs qui attendent le véritable exactitude mathématique—voir Javascript toFixed Pas Arrondi et cette "fonctionne comme prévu" bug qui a été déposée sur le V8 JS moteur pour des exemples.Conclusion
En bref, ce sont deux fonctions différentes avec deux différents types de retour et deux ensembles différents de règles de l'arrondi.
Comme d'autres l'ont suggéré, je voudrais également dire "utiliser n'importe quelle fonction correspond à votre cas d'utilisation particulier" (en prenant soin de noter les particularités de
toFixed
, en particulier IE errant mise en œuvre).personnellement, je ne penche plus vers la recommandation explicite de la combinaison deEdit: ...mais, après un va-et la lecture de vos précisions, vos cas d'utilisation (arrondi à un nombre entier) appelle définitivement pour la bien-nomméeMath.round/ceil/floor
, encore une fois, comme d'autres l'ont mentionné.Math.round
fonction.toFixed
n'est pas buggé, juste très peu intuitive.toFixed() renvoie une chaîne de valeur. À Partir De Javascript: The Definitive Guide
Mathématiques.round() renvoie un entier.
Clairement, toFixed() semblent être plus à l'utiliser pour de l'argent, par exemple,
Il semble un grand dommage que toFixed() ne semble pas rond correctement!
Au lieu de
toFixed(0)
utilisationMath.ceil()
ouMath.floor()
, selon ce qui est requis.Il semble de cette façon, si vous obtenez des réponses incohérentes.
Je ne peux que deviner que votre intention usin toFixed(0) est de transformer un nombre décimal en un nombre entier, à quel point je vous recommande de Mathématiques.floor(). Il y a un peu plus de discussion sur la meilleure façon de le faire dans cette question.