¿Cómo lidiar con la precisión del número de coma flotante en JavaScript?


Tengo el siguiente script de prueba ficticio:

function test(){
    var x = 0.1 * 0.2;
    document.write(x);
}
test();

Esto imprimirá el resultado 0.020000000000000004 mientras que solo debería imprimir 0.02 (si usa su calculadora). Por lo que he entendido esto se debe a errores en la precisión de multiplicación en coma flotante.

¿Alguien tiene una buena solución para que en tal caso obtenga el resultado correcto 0.02? Sé que hay funciones como toFixed o redondear sería otra posibilidad, pero me gustaría realmente tener el número entero impreso sin ninguna cortar y redondear. Sólo quería saber si uno de ustedes tiene alguna solución agradable y elegante.

Por supuesto, de lo contrario redondearé a unos 10 dígitos más o menos.

Author: Web_Designer, 2009-09-22

30 answers

De la Guía de Punto Flotante :

¿Qué puedo hacer para evitar este problema?

Eso depende de qué tipo de cálculos que estás haciendo.

  • Si realmente necesita que sus resultados se sumen exactamente, especialmente cuando trabajar con dinero: usar un decimal especial tipo de datos.
  • Si simplemente no quieres ver todos esos decimales adicionales: simplemente formatee su resultado redondeado a un fijo número de decimales cuando mostrándolo.
  • Si no tiene un tipo de datos decimal disponible, una alternativa es trabajar con enteros, por ejemplo, hacer dinero cálculos totalmente en centavos. Pero esto es más trabajo y tiene algunos inconveniente.

Tenga en cuenta que el primer punto solo se aplica si realmente necesita un comportamiento preciso decimal específico. La mayoría de las personas no necesitan eso, simplemente están irritados de que sus programas no funcionan correctamente con números como 1/10 sin darse cuenta de que ni siquiera parpadearía ante el mismo error si ocurriera con 1/3.

Si el primer punto realmente se aplica a usted, use BigDecimal para JavaScript, que no es elegante en absoluto, pero en realidad resuelve el problema en lugar de proporcionar una solución imperfecta.

 390
Author: Michael Borgwardt,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-12-01 08:40:53

Me gusta la solución de Pedro Ladaria y uso algo similar.

function strip(number) {
    return (parseFloat(number).toPrecision(12));
}

A diferencia de la solución de Pedros, esto redondeará 0.999...repitiendo y es exacto a más / menos uno en el dígito menos significativo.

Nota: Cuando se trata de flotadores de 32 o 64 bits, debe usar toPrecision(7) y toPrecision(15) para obtener mejores resultados. Vea esta pregunta para obtener información sobre por qué.

 96
Author: linux_mike,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:18:17

Para los matemáticamente inclinados: http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html

El enfoque recomendado es usar factores de corrección (multiplicar por una potencia adecuada de 10 para que la aritmética ocurra entre enteros). Por ejemplo, en el caso de 0.1 * 0.2, el factor de corrección es 10, y usted está realizando el cálculo:

> var x = 0.1
> var y = 0.2
> var cf = 10
> x * y
0.020000000000000004
> (x * cf) * (y * cf) / (cf * cf)
0.02

Una solución (muy rápida) se ve algo así como:

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); };

En este caso:

> Math.m(0.1, 0.2)
0.02

Definitivamente recomendar el uso de una biblioteca probada como SinfulJS

 56
Author: SheetJS,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-09-20 02:55:52

¿Solo estás haciendo multiplicación? Si es así, entonces usted puede utilizar a su ventaja un secreto limpio sobre la aritmética decimal. Eso es NumberOfDecimals(X) + NumberOfDecimals(Y) = ExpectedNumberOfDecimals. Es decir que si tenemos 0.123 * 0.12 entonces sabemos que habrá 5 decimales porque 0.123 tiene 3 decimales y 0.12 tiene dos. Por lo tanto, si JavaScript nos dio un número como 0.014760000002 podemos redondear con seguridad a la 5ª posición decimal sin temor a perder precisión.

 35
Author: Nate Zaugg,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-15 18:10:23

Está buscando una implementación sprintf para JavaScript, para que pueda escribir flotadores con pequeños errores en ellos (ya que están almacenados en formato binario) en un formato que usted espera.

Intenta javascript-sprintf , lo llamarías así:

var yourString = sprintf("%.2f", yourNumber);

Para imprimir su número como un flotador con dos decimales.

También puede usar Número.toFixed () para fines de visualización, si prefiere no incluir más archivos simplemente para coma flotante redondeo a una precisión dada.

 24
Author: Douglas,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-01-05 01:55:50
var times = function (a, b) {
    return Math.round((a * b) * 100)/100;
};

---o---

var fpFix = function (n) {
    return Math.round(n * 100)/100;
};

fpFix(0.1*0.2); // -> 0.02

---también---

var fpArithmetic = function (op, x, y) {
    var n = {
            '*': x * y,
            '-': x - y,
            '+': x + y,
            '/': x / y
        }[op];        

    return Math.round(n * 100)/100;
};

- - - como en - - -

fpArithmetic('*', 0.1, 0.2);
// 0.02

fpArithmetic('+', 0.1, 0.2);
// 0.3

fpArithmetic('-', 0.1, 0.2);
// -0.1

fpArithmetic('/', 0.2, 0.1);
// 2
 14
Author: shawndumas,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-08-09 12:14:25

Esta función determinará la precisión necesaria a partir de la multiplicación de dos números de coma flotante y devolverá un resultado con la precisión adecuada. Elegante aunque no lo es.

function multFloats(a,b){
  var atens = Math.pow(10,String(a).length - String(a).indexOf('.') - 1), 
      btens = Math.pow(10,String(b).length - String(b).indexOf('.') - 1); 
  return (a * atens) * (b * btens) / (atens * btens); 
}
 14
Author: Gabriel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-10-13 13:45:39

Estoy encontrando BigNumber.js satisface mis necesidades.

Una biblioteca JavaScript para aritmética decimal y no decimal de precisión arbitraria.

Tiene buena documentación y el autor es muy diligente respondiendo a los comentarios.

El mismo autor tiene otras 2 bibliotecas similares:

Grande.js

Una pequeña y rápida biblioteca JavaScript para aritmética decimal de precisión arbitraria. Hermanita a bignumber.js.

Y Decimal.js

Un tipo decimal de precisión arbitraria para JavaScript.

Aquí hay un código usando BigNumber:

$(function(){

  
  var product = BigNumber(.1).times(.2);  
  $('#product').text(product);

  var sum = BigNumber(.1).plus(.2);  
  $('#sum').text(sum);


});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>

<!-- 1.4.1 is not the current version, but works for this example. -->
<script src="http://cdn.bootcss.com/bignumber.js/1.4.1/bignumber.min.js"></script>

.1 &times; .2 = <span id="product"></span><br>
.1 &plus; .2 = <span id="sum"></span><br>
 13
Author: Ronnie Overby,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-12-02 14:35:50

Solo tienes que decidir cuántos dígitos decimales quieres realmente-no puedes tener el pastel y comerlo también: -)

Los errores numéricos se acumulan con cada operación posterior y si no lo cortas antes, simplemente crecerá. Las bibliotecas numéricas que presentan resultados que parecen limpios simplemente cortan los últimos 2 dígitos en cada paso, los coprocesadores numéricos también tienen una longitud" normal "y" completa " por la misma razón. Cuf-offs son baratos para un procesador, pero muy caro para usted en un script (multiplicando y dividiendo y usando pov(...)). Una buena biblioteca de matemáticas proporcionaría piso (x, n) para hacer el corte por usted.

Así que al menos deberías hacer var/constante global con pov (10, n) - lo que significa que decidiste la precisión que necesitas: -) Entonces haz:

Math.floor(x*PREC_LIM)/PREC_LIM  // floor - you are cutting off, not rounding

También podría seguir haciendo matemáticas y solo cortar al final, asumiendo que solo está mostrando y no haciendo if-s con resultados. Si puedes hacer eso, entonces .toFixed(...) podría ser más eficiente.

Si está haciendo comparaciones if-s/y no quiere cortar de entonces también necesita una pequeña constante, generalmente llamada eps, que es un lugar decimal más alto que el error máximo esperado. Digamos que su corte es los últimos dos decimales - entonces su eps tiene 1 en el 3er lugar del último (3er menos significativo) y puede usarlo para comparar si el resultado está dentro del rango de eps esperado (0.02-eps

 10
Author: ZXX,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-08-06 08:30:54

La función round () en phpjs.org funciona muy bien: http://phpjs.org/functions/round

num = .01 + .06;  // yields 0.0699999999999
rnum = round(num,12); // yields 0.07
 8
Author: Tom,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-03-01 19:50:30

El resultado que tienes es correcto y bastante consistente a través de implementaciones de coma flotante en diferentes lenguajes, procesadores y sistemas operativos - lo único que cambia es el nivel de inexactitud cuando el flotador es en realidad un doble (o superior).

0.1 en puntos flotantes binarios es como 1/3 en decimal (es decir, 0.33333333333333... para siempre), simplemente no hay una manera precisa de manejarlo.

Si está tratando con flotadores siempre espere pequeños errores de redondeo, así que siempre tendrás que redondear el resultado mostrado a algo sensible. A cambio obtienes aritmética muy, muy rápida y poderosa porque todos los cálculos están en el binario nativo del procesador.

La mayoría de las veces la solución no es cambiar a la aritmética de punto fijo, principalmente porque es mucho más lenta y el 99% de las veces simplemente no necesita la precisión. Si está tratando con cosas que necesitan ese nivel de precisión (por ejemplo, transacciones financieras) Javascript probablemente no es la mejor herramienta para usar de todos modos (ya que desea hacer cumplir los tipos de punto fijo, un lenguaje estático es probablemente mejor).

Está buscando la solución elegante, entonces me temo que esto es todo: los flotadores son rápidos pero tienen pequeños errores de redondeo, siempre redondeados a algo sensible al mostrar sus resultados.

 6
Author: Keith,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-08-09 08:57:20

Para evitar esto, debe trabajar con valores enteros en lugar de puntos flotantes. Así que cuando usted quiere tener 2 posiciones de trabajo de precisión con los valores * 100, para 3 posiciones utilizar 1000. Cuando se muestra se utiliza un formateador para poner en el separador.

Muchos sistemas omiten trabajar con decimales de esta manera. Esa es la razón por la que muchos sistemas funcionan con centavos (como entero) en lugar de dólares/euros (como punto flotante).

 6
Author: Gertjan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-08-09 12:12:52

Puede usar parseFloat() y toFixed() si desea evitar este problema para una operación pequeña:

a = 0.1;
b = 0.2;

a + b = 0.30000000000000004;

c = parseFloat((a+b).toFixed(2));

c = 0.3;

a = 0.3;
b = 0.2;

a - b = 0.09999999999999998;

c = parseFloat((a-b).toFixed(2));

c = 0.1;
 5
Author: Softwareddy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-04-10 11:38:13

Sorprendentemente, esta función no se ha publicado todavía, aunque otros tienen variaciones similares de la misma. Es de los documentos web de MDN para Matemáticas.ronda(). Es conciso y permite una precisión variable.

function precisionRound(number, precision) {
  var factor = Math.pow(10, precision);
  return Math.round(number * factor) / factor;
}

Consola.log (precisionRound(1234.5678, 1)); // producto previsto: 1234,6

Consola.log (precisionRound(1234.5678, -1)); // producción prevista: 1230

var inp = document.querySelectorAll('input');
var btn = document.querySelector('button');

btn.onclick = function(){
  inp[2].value = precisionRound( parseFloat(inp[0].value) * parseFloat(inp[1].value) , 5 );
};

//MDN function
function precisionRound(number, precision) {
  var factor = Math.pow(10, precision);
  return Math.round(number * factor) / factor;
}
button{
display: block;
}
<input type='text' value='0.1'>
<input type='text' value='0.2'>
<button>Get Product</button>
<input type='text'>
 5
Author: HelloWorldPeace,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-04-09 09:30:11

0.6 * 3 ¡es increíble!)) Para mí esto funciona bien:

function dec( num )
{
    var p = 100;
    return Math.round( num * p ) / p;
}

Muy muy simple))

 4
Author: Олег Всильдеревьев,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-02-12 09:14:30

Echa un vistazo a aritmética de punto fijo. Probablemente resolverá su problema, si el rango de números en los que desea operar es pequeño (por ejemplo, moneda). Lo redondearía a unos pocos valores decimales, que es la solución más simple.

 3
Author: Marius,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-09-22 07:39:09

Prueba mi biblioteca aritmética chiliádica, que puedes ver aquí. Si quieres una versión posterior, puedo conseguirte una.

 3
Author: Robert L,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-10-06 00:04:02

No puede representar la mayoría de las fracciones decimales exactamente con tipos binarios de coma flotante (que es lo que ECMAScript usa para representar valores de coma flotante). Por lo tanto, no hay una solución elegante a menos que use tipos aritméticos de precisión arbitraria o un tipo de coma flotante basado en decimales. Por ejemplo, la aplicación Calculadora que viene con Windows ahora usa aritmética de precisión arbitraria para resolver este problema.

 3
Author: MSN,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-08-05 17:44:35

Problema

El punto flotante no puede almacenar todos los valores decimales exactamente. Así que cuando se utilizan formatos de coma flotante siempre habrá errores de redondeo en los valores de entrada. Los errores en las entradas de resultados de curso en los errores en la salida. En el caso de una función u operador discreto puede haber grandes diferencias en la salida alrededor del punto donde la función u operador es discreto.

Entrada y salida para valores de coma flotante

Entonces, al usar variables de coma flotante, siempre debe ser consciente de esto. Y cualquier salida que desee de un cálculo con puntos flotantes siempre debe ser formateado / condicionado antes de mostrar con esto en mente.
Cuando solo se utilizan funciones y operadores continuos, redondear a la precisión deseada a menudo servirá (no truncar). Las características de formato estándar utilizadas para convertir flotadores a cadena generalmente harán esto por usted.
Porque el redondeo agrega un error que puede causar el total error para ser más de la mitad de la precisión deseada, la salida debe corregirse en función de la precisión esperada de las entradas y la precisión deseada de la salida. Usted debe

  • Redondee las entradas a la precisión esperada o asegúrese de que no se puedan ingresar valores con mayor precisión.
  • Agregue un pequeño valor a las salidas antes de redondearlas / formatearlas que sea menor o igual a 1/4 de la precisión deseada y mayor que el error máximo esperado causado por los errores de redondeo en entrada y durante el cálculo. Si eso no es posible, la combinación de la precisión del tipo de datos utilizado no es suficiente para entregar la precisión de salida deseada para su cálculo.

Estas 2 cosas generalmente no se hacen y en la mayoría de los casos las diferencias causadas por no hacerlas son demasiado pequeñas para ser importantes para la mayoría de los usuarios, pero ya tenía un proyecto donde la salida no fue aceptada por los usuarios sin esas correcciones.

Funciones u operadores discretos (como modula)

Cuando se trata de operadores o funciones discretos, es posible que se requieran correcciones adicionales para asegurarse de que la salida sea la esperada. Redondear y agregar pequeñas correcciones antes de redondear no puede resolver el problema.
Es posible que se requiera una comprobación/corrección especial de los resultados del cálculo intermedio, inmediatamente después de aplicar la función discreta o el operador. Para un caso específico (operador de modula), vea mi respuesta a la pregunta: ¿Por qué el operador de módulo devuelve fraccional número en javascript?

Mejor evitar tener el problema

A menudo es más eficiente evitar estos problemas mediante el uso de tipos de datos (enteros o formatos de punto fijo) para cálculos como este que pueden almacenar la entrada esperada sin errores de redondeo. Un ejemplo de esto es que nunca debe usar valores de coma flotante para cálculos financieros.

 3
Author: Stefan Mondelaers,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-07-27 14:04:12

Use

var x = 0.1*0.2;
 x =Math.round(x*Math.pow(10,2))/Math.pow(10,2);
 2
Author: Himadri,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-09-22 08:15:26

No es elegante pero hace el trabajo (elimina los ceros finales)

var num = 0.1*0.2;
alert(parseFloat(num.toFixed(10))); // shows 0.02
 1
Author: Peter,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-09-22 12:48:50

Tienes razón, la razón de eso es la precisión limitada de los números de coma flotante. Almacene sus números racionales como una división de dos números enteros y en la mayoría de las situaciones podrá almacenar números sin ninguna pérdida de precisión. Cuando se trata de imprimir, es posible que desee mostrar el resultado como fracción. Con la representación que propuse, se vuelve trivial.

Por supuesto que eso no ayudará mucho con los números irracionales. Pero es posible que desee optimizar sus cálculos en la forma en que causará el menor problema (por ejemplo, detectando situaciones como sqrt(3)^2).

 1
Author: skalee,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-08-07 11:21:26

Número de uso (1.234443).toFixed (2); imprimirá 1.23

function test(){
    var x = 0.1 * 0.2;
    document.write(Number(x).toFixed(2));
}
test();
 1
Author: Harish.bazee,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-10-08 10:46:17

Tuve un desagradable problema de error de redondeo con mod 3. A veces, cuando debería obtener 0, obtendría .000...01. Eso es bastante fácil de manejar, solo prueba para

BigNumbers resolvió el problema, pero introdujo otro, algo irónico, problema. Al intentar cargar 8.5 en BigNumbers me informaron que era realmente 8.4999 really y tenía más de 15 dígitos significativos. Esto significaba que los BigNumbers no podían aceptarlo (creo que mencionado este problema era algo irónico).

Solución simple al problema irónico:

x = Math.round(x*100);
// I only need 2 decimal places, if i needed 3 I would use 1,000, etc.
x = x / 100;
xB = new BigNumber(x);
 1
Author: mcgeo52,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-12-14 17:34:22

introduzca la descripción de la imagen aquí

    You can use library https://github.com/MikeMcl/decimal.js/. 
    it will   help  lot to give proper solution. 
    javascript console output 95 *722228.630 /100 = 686117.1984999999
    decimal library implementation 
    var firstNumber = new Decimal(95);
    var secondNumber = new Decimal(722228.630);
    var thirdNumber = new Decimal(100);
    var partialOutput = firstNumber.times(secondNumber);
    console.log(partialOutput);
    var output = new Decimal(partialOutput).div(thirdNumber);
    alert(output.valueOf());
    console.log(output.valueOf())== 686117.1985
 1
Author: Ashish Singhal,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-05-28 11:45:11

Observe que para el uso de propósito general, este comportamiento es probable que sea aceptable.
El problema surge al comparar esos valores de puntos flotantes para determinar una acción apropiada.
Con el advenimiento de ES6, se define una nueva constante Number.EPSILON para determinar el margen de error aceptable:
Así que en lugar de realizar la comparación como esta

0.1 + 0.2 === 0.3 // which returns false

Puede definir una función de comparación personalizada, como esta:

function epsEqu(x, y) {
    return Math.abs(x - y) < Number.EPSILON;
}
console.log(epsEqu(0.1+0.2, 0.3)); // true

Fuente : http://2ality.com/2015/04/numbers-math-es6.html#numberepsilon

 1
Author: user10089632,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-09-15 23:44:42

Esto funciona para mí:

function round_up( value, precision ) { 
    var pow = Math.pow ( 10, precision ); 
    return ( Math.ceil ( pow * value ) + Math.ceil ( pow * value - Math.ceil ( pow * value ) ) ) / pow; 
}

round_up(341.536, 2); // 341.54
 0
Author: Antonio Max,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-10-03 19:29:26

Salida usando la siguiente función:

var toFixedCurrency = function(num){
    var num = (num).toString();
    var one = new RegExp(/\.\d{1}$/).test(num);
    var two = new RegExp(/\.\d{2,}/).test(num);
    var result = null;

    if(one){ result = num.replace(/\.(\d{1})$/, '.$10');
    } else if(two){ result = num.replace(/\.(\d{2})\d*/, '.$1');
    } else { result = num*100; }

    return result;
}

function test(){
    var x = 0.1 * 0.2;
    document.write(toFixedCurrency(x));
}

test();

Presta atención a la salida toFixedCurrency(x).

 0
Author: Júlio Paulillo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-06-19 23:51:05

Mientras se agregan dos valores flotantes, nunca se dan los valores precisos, por lo que necesitamos fijar esto a cierto número que nos ayudará a comparar.

consola.log ((parseFloat (0.1) + parseFloat (0.2)).toFixed(1) = = parseFloat (0.3).toFixed(1));
 0
Author: aditya,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-07-14 09:09:19

No soy muy bueno programando, pero estaba realmente interesado en este tema, así que traté de entender cómo resolver eso sin usar ninguna biblioteca o script

Escribí esto en scratchpad

var toAlgebraic = function(f1, f2) {
    let f1_base = Math.pow(10, f1.split('.')[1].length);
    let f2_base = Math.pow(10, f2.split('.')[1].length);
    f1 = parseInt(f1.replace('.', ''));
    f2 = parseInt(f2.replace('.', ''));

    let dif, base;
    if (f1_base > f2_base) {
        dif = f1_base / f2_base;
        base = f1_base;
        f2 = f2 * dif;
    } else {
        dif = f2_base / f1_base;
        base = f2_base;
        f1 = f1 * dif;
    }

    return (f1 * f2) / base;
};

console.log(0.1 * 0.2);
console.log(toAlgebraic("0.1", "0.2"));

Puede que necesites refactorizar este código, porque no soy bueno programando:)

 0
Author: Jeeva,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-07-10 11:13:22