web-dev-qa-db-fra.com

Faire face à la précision du flottant en Javascript

J'ai une grande quantité de valeurs numériques y en javascript. Je veux les regrouper en les arrondissant au multiple de x le plus proche et convertir le résultat en chaîne.

Comment puis-je contourner la gênante précision en virgule flottante?

Par exemple:

0.2 + 0.4 = 0.6000000000000001

Deux choses que j'ai essayées:

>>> y = 1.23456789 
>>> x = 0.2 
>>> parseInt(Math.round(Math.floor(y/x))) * x; 
1.2000000000000002

et:

>>> y = 1.23456789 
>>> x = 0.2 
>>> y - (y % x)
1.2000000000000002
81
Jeroen

De cette publication: Comment gérer la précision des nombres à virgule flottante en JavaScript?

Vous avez quelques options:

  • Utilisez un type de données spécial pour les décimales, tel que decimal.js
  • Formatez votre résultat avec un nombre fixe de chiffres significatifs, comme ceci: (Math.floor(y/x) * x).toFixed(2)
  • Convertissez tous vos nombres en nombres entiers
110
Rusty Fausak

Vous pouvez faire quelque chose comme ça:

> +(Math.floor(y/x)*x).toFixed(15);
1.2
5
philipvr
> var x = 0.1
> var y = 0.2
> var cf = 10
> x * y
0.020000000000000004
> (x * cf) * (y * cf) / (cf * cf)
0.02

Solution rapide:

var _cf = (function() {
  function _shift(x) {
    var parts = x.toString().split('.');
    return (parts.length < 2) ? 1 : Math.pow(10, parts[1].length);
  }
  return function() { 
    return Array.prototype.reduce.call(arguments, function (prev, next) { return prev === undefined || next === undefined ? undefined : Math.max(prev, _shift (next)); }, -Infinity);
  };
})();

Math.a = function () {
  var f = _cf.apply(null, arguments); if(f === undefined) return undefined;
  function cb(x, y, i, o) { return x + f * y; }
  return Array.prototype.reduce.call(arguments, cb, 0) / f;
};

Math.s = function (l,r) { var f = _cf(l,r); return (l * f - r * f) / f; };

Math.m = function () {
  var f = _cf.apply(null, arguments);
  function cb(x, y, i, o) { return (x*f) * (y*f) / (f * f); }
  return Array.prototype.reduce.call(arguments, cb, 1);
};

Math.d = function (l,r) { var f = _cf(l,r); return (l * f) / (r * f); };

> Math.m(0.1, 0.2)
0.02

Vous pouvez vérifier l'explication complète ici .

4
Hamza Alayed

Consultez ce lien .. Cela m'a beaucoup aidé.

http://www.w3schools.com/jsref/jsref_toprecision.asp

La fonction toPrecision(no_of_digits_required) renvoie un string. N'oubliez donc pas d'utiliser la fonction parseFloat() pour convertir le point décimal avec la précision requise.

1
prahaladp

Pour aborder cette tâche, je commencerais par trouver le nombre de décimales dans x, puis d’arrondir y en conséquence. J'utiliserais:

y.toFixed(x.toString().split(".")[1].length);

Il doit convertir x en chaîne, le diviser en plusieurs décimales, trouver la longueur de la partie droite, puis y.toFixed(length) doit arrondir y en fonction de cette longueur.

0
whaatt