Pourquoi le module opérateur renvoie le nombre fractionnaire en javascript?
Pourquoi ne 49.90 % 0.10
en JavaScript retour 0.09999999999999581
? Je m'attendais à être 0.
- Floating point encore 🙁
- Voir [Est du JavaScript Math cassé? ](stackoverflow.com/questions/588004/is-javascripts-math-broken).
- Voir: Python modulo sur flotteurs (différent de la langue, mais la question -- virgule flottante erreur-est le même)
Vous devez vous connecter pour publier un commentaire.
Parce que JavaScript utilise le calcul en virgule flottante qui conduit toujours à des erreurs d'arrondi.
Si vous avez besoin d'un résultat exact avec deux décimales, multipliez vos numéros avec
100
avant l'opération, puis de diviser à nouveau par la suite:Tour si nécessaire.
(40.55 * 100 %1000)/100
retourne 0.549999... au lieu de 0,55.Javascript du Numéro à l'aide de "double-précision IEEE" pour stocker les valeurs. Ils sont incapables de stocker tous les nombres décimaux exactement. Le résultat n'est pas nul, en raison de l'erreur d'arrondi lors de la conversion du nombre décimal en binaire.
Ainsi plancher(49.90 /0.10) est seulement 498, et le reste sera 0.09999....
Il me semble que vous êtes en utilisant des numéros de stocker quantité de dollars. Ne faites pas cette, comme d'opérations en virgule flottante de propager et d'amplifier l'erreur d'arrondi. Enregistrer le numéro de la quantité de cents à la place. Entier peut être représenté exactement, et
4990 % 10
sera de retour 0.Je vais juste laisser ça ici pour référence future, mais ici, c'est une fonction très pratique qui peut plus précisément poignée Reste (depuis JS n'est pas un opérateur modulo) impliquant des chars.
JS:
HTML:
return (((valInt % stepInt) + stepInt) % stepInt) / Math.pow(10, decCount)
Cause
À virgule flottante ne peut pas stocker toutes les valeurs décimales exactement. Donc, lorsque vous utilisez floating point format, il y aura toujours des erreurs d'arrondi sur les valeurs d'entrée.
Les erreurs sur les données de résultats de cours sur les erreurs sur la sortie.
Dans le cas d'une fonction discrète ou de l'opérateur, il peut y avoir une grande différence sur la sortie de autour du point où la fonction ou de l'opérateur est discret.
Le modula opérateur est discret et votre cas est clairement un exemple de ce problème.
D'entrée et de sortie pour les valeurs à virgule flottante
Donc, lors de l'utilisation de variables à virgule flottante, vous devriez toujours être conscient de cela. Et quelle que soit la sortie que vous voulez à partir d'un calcul avec floating points doivent toujours être formaté/conditionnés avant d'afficher avec cela à l'esprit.
Lorsque seules des fonctions continues et les opérateurs sont utilisés, arrondi à la précision souhaitée souvent faire (ne pas tronquer). Standard de fonctionnalités de mise en forme utilisé pour convertir les flotteurs pour la chaîne va généralement de le faire pour vous.
Pour avoir un bon de sortie en fonction de la précision des entrées et de la précision souhaitée de sortie, vous devez également
Ces 2 choses sont souvent pas faite et, dans la plupart des cas, les différences causées par ne pas les faire trop petits pour être important pour la plupart des utilisateurs, mais j'ai déjà eu un projet où la production n'a pas été acceptée par les utilisateurs sans que ces corrections.
Fonctions discrètes ou des opérateurs (comme modula)
Lorsque discret opérateurs ou fonctions sont impliqués, corrections supplémentaires pourraient être nécessaires pour assurer que la sortie est aussi prévue. L'arrondi et l'ajout de petites corrections avant l'arrondi ne pouvez pas résoudre le problème.
Une spéciale de vérification/correction sur les intermédiaires de résultats de calcul, immédiatement après l'application de la fonction discrète ou l'exploitant peut être nécessaire.
Cas particulier de cette question
Dans ce cas, vous vous attendez d'entrée avec une certaine précision, de sorte qu'il est possible de corriger la sortie de l'impact des erreurs d'arrondi qui sont beaucoup plus petites que la précision souhaitée.
Si nous disons que la précision de vos données est de type e.
Vos commentaires ne seront pas stockées comme les valeurs de a et b que vous avez entré, mais a*(1+/-e) et b*(1+/e -)
Le résultat d'une division a*(1+/-e) par b*(1+/-e) aurait pour conséquence (a/b)(1+/-2e).
Le modula fonction a pour tronquer le résultat et se multiplier encore.
De sorte que le résultat sera (a/bb)(1+/-3e) = a(1+/-3e), ce qui entraîne une erreur d'un*3e.
Le mod ajoute un*e de l'erreur d'un*3e en raison de la soustraction de 2 valeurs avec une possible erreur de*3e et un*e.
Vous devez donc vérifier que le total de la possible erreur a*4e est plus petite que la précision souhaitée et si cette condition est remplie et que le résultat diffère pas de plus de b que le maximum d'erreur possible, vous pouvez le remplacer par 0.
Mieux éviter d'avoir le problème
Il est souvent plus efficace d'éviter ces problèmes en utilisant des types de données (entier ou à virgule fixe formats) pour les calculs comme ce qui peut stocker les données à saisir sans les erreurs d'arrondi.
Un exemple est que vous ne devez jamais utiliser des valeurs à virgule flottante pour les calculs financiers.
http://en.wikipedia.org/wiki/Modulo_operation
Ne soyez pas en colère modulo est utilisé avec des entiers ^^
Donc, les valeurs flottantes survenir dans certaines erreurs.
Prendre un coup d'oeil à floating points et ses inconvénients - un nombre comme
0.1
ne peuvent pas être enregistrées correctement la virgule flottante, donc il y aura toujours de tels problèmes. Prenez vos chiffres *10 ou *100 et de faire les calculs avec des entiers à la place.Ce n'est pas une réponse parfaite, mais il fonctionne.
vous pouvez utiliser comme suit,
car en-dessous du numéro (49.89999999999999857891452848) 15 premières décimales sont comme 9999999