Foros del Web » Programando para Internet » Javascript »

Ayuda!!! Sumas y restas no exactas

Estas en el tema de Ayuda!!! Sumas y restas no exactas en el foro de Javascript en Foros del Web. Hola tal, pues tengo un pequeño problema con unos calculos que necesito hacer Tengo una caja de texto en donde introducen un valor y necesito ...
  #1 (permalink)  
Antiguo 02/01/2008, 13:06
 
Fecha de Ingreso: octubre-2007
Mensajes: 36
Antigüedad: 16 años, 6 meses
Puntos: 0
Ayuda!!! Sumas y restas no exactas

Hola tal, pues tengo un pequeño problema con unos calculos que necesito hacer
Tengo una caja de texto en donde introducen un valor y necesito restarle 0.32 o 0.25, segun sea un caso.

Ahora, en algunos casos si realiza ese calculo bien (vamos, como deberia de ser en una calculadora) pero en otros no.

Por ejemplo, cuando introduzco 2.32 y le tiene que restar 0.32, su resultado sería 2, pero me da 1.9999999999999998
(si hago la resta 3.32 menos 0.32 si me retorna el 3, como deberia de ser. Pero con algunas otras cifras no siempre es el resultado correcto).

Les dejo el codigo, no se si sea cuestion de javascript o de mi codigo (aunque bueno, no es nada del otro mundo)

Código:
function fn_psuc(nombre)
{
	var valor2;
	var algo=nombre.substring(4,10);
	var anio = document.form.anio.value;
	Number (valor = eval("document.form."+nombre+".value"));
	valor2 = Number(valor);
	var algo2 = "psuc" + algo;
	//valor = Number(valor) + Number(valor2);
	//alert(valor3);
	if(anio==2007)
	{
		if(algo!=39)
		{
			valor = Number(valor) - 0.32;
			valor2 = Number(valor) + 0.32;
		}
		else
		{
			valor = Number(valor) - 0.25;
			valor2 = Number(valor) + 0.25;
		}
	}
	eval("document.form."+algo2+".value = "+valor+"");
}
Disculpen por las variables xDDD, pero es algo que apenas estoy probando. Utilizo el formato "Number" porque en ocasiones toma la variable como cadena y no como numero.

Gracias de antemano.
Saludos!!!
  #2 (permalink)  
Antiguo 02/01/2008, 17:39
Avatar de derkenuke
Colaborador
 
Fecha de Ingreso: octubre-2003
Ubicación: self.location.href
Mensajes: 2.665
Antigüedad: 20 años, 6 meses
Puntos: 45
Re: Ayuda!!! Sumas y restas no exactas

Bueno Angel_Cruijff:

Tengo que decirte que has descubierto un BUG -no famoso- de javascript. Y contra el que no podemos luchar. Lo único que se puede hacer es usar Math.round(), o algo así.

El bug no se queda ahí, fallan muchas más cosas. Falla la suma de elementos decimales, falla la multiplicación... como ves o_O

¿Cuánto dirías que da 0.1*0.1? Exacto, da 0.010000000000000002.
Tampoco hay que ir tan lejos. ¿0.2+0.1? Bien: 0.30000000000000004

En números enteros (integer) no he encontrado nada... Menos mal.

He hecho un pequeño script que revela que para multiplicaciones de números de una décima tenemos un montón de errores. Se apoya en multiplicar los números sumándolos (3*2 = 3+3), y comparar esos dos resultados.

Código:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="es" lang="es">
<head>
<meta http-equiv="Content-type" content="text/html;charset=iso-8859-1" />
<meta name="Author" content="derkeNuke" />
<title>Bug de Math en javascript</title>
<style type="text/css">

</style>
</head>

<body>


<script type="text/javascript">
<!--


// escribir en el documento una ristra (x)html fuera de tiempo de ejecución.
function e(q,sinBR) {
	var elDIV = document.createElement("DIV");
	if(q==undefined) q="";
	if(!sinBR) q+="<br/>";
	elDIV.innerHTML = q;
	for(var a=0; elDIV.childNodes.length>a; a++) {
		document.body.appendChild( elDIV.childNodes[a].cloneNode(true) );
	}
}



// Si x = 0.04 nos devuelve [4, 100]. El número en entero y el multiplicador necesario para ello.
function aEntero(x) {
	var multiplicador = 1;
	while( x!=parseInt(x) ) {
		multiplicador *= 10;
		// corremos la coma 1 posicion
		x = Number( x.toString().replace(/(\.)(\d)/, "$2$1") );
	}
	return [x, multiplicador];
}

// Multiplicación manual: Multiplica dos números sumando y veces el x
function m(x,y) {
	x = aEntero(x);
	y = aEntero(y);
	var mult = x[1] * y[1];
	for(var i=0, r=0; i<y[0]; i++)
		r+=x[0];
	return r/mult;
}

// Compara la multiplicación nativa con la manual, devuelve true si no son iguales (si hay bug)
function hayBug(x,y) {
	var mult = (x*y);
	var bien = m(x,y);
	var o = [ (mult!=bien), bien, mult ];
	o.toString = function() { return this[0]; }
	return o;
}


// Bucle principal
for(var i=0; i<1; i+=0.1, i=Math.round(i*10)/10 ) {
	for(var j=0; j<1; j+=0.1, j=Math.round(j*10)/10 ) {
		var b = hayBug(i,j);
		if( b[0] ) {
			e( i+"*"+j+" = "+ b[1] +", pero da "+b[2] );
		}
	}
	e();
}

// -->
</script>

</body>
</html>


Bueno, no sé si posteé sobre esto hace tiempo, no lo he encontrado -de todas maneras no habría tenido respuestas, me acordaría- pero si alguien sabe de este tema, o de sitios donde hablen de ello y la 'regla' que lo produce, que lo postee por favor.

A estas alturas y con bugs tan gordos...




Un saludo y a ver si se agregan más detalles de ésto
__________________
- Haz preguntas inteligentes, y obtendrás más y mejores respuestas.
- Antes de postearlo Inténtalo y Búscalo.
- Escribe correctamente tus mensajes.
  #3 (permalink)  
Antiguo 02/01/2008, 19:16
Avatar de derkenuke
Colaborador
 
Fecha de Ingreso: octubre-2003
Ubicación: self.location.href
Mensajes: 2.665
Antigüedad: 20 años, 6 meses
Puntos: 45
Re: Ayuda!!! Sumas y restas no exactas

He encontrado este link que habla de ello:

JavaScript Math Errors in Netscape & Internet Explorer
Bueno, lo primero: Es de September 8, 1998 ( ¿casi diez años? Si... )
Lo segundo es que concluye ciertas cosas, hablando de 81.66*15:
Cita:
Iniciado por http://www.astonisher.com/archives/bugnet/alerts/bugalert9298.html
The decimal number 81.66 can not be exactly translated into binary form
Con eso casi se justifica todo. Se afirma que hasta C tiene ese problema (mientras que se prueba en PERL y no...). Se comenta que la calculadora de Windows 95 devuelve bien ese valor porque redondea.

Al parecer es un problema más serio que de simple javascript.


Cita:
Iniciado por http://www.astonisher.com/archives/bugnet/alerts/bugalert9298.html
For now, there is no fix and no work-around for this problem, except to keep a pocket calculator handy and not believe everything you read on the screen.

The answer supplied by your PC may be wrong. And the wrong answer may be right.
__________________
- Haz preguntas inteligentes, y obtendrás más y mejores respuestas.
- Antes de postearlo Inténtalo y Búscalo.
- Escribe correctamente tus mensajes.
  #4 (permalink)  
Antiguo 02/01/2008, 21:44
 
Fecha de Ingreso: octubre-2007
Mensajes: 36
Antigüedad: 16 años, 6 meses
Puntos: 0
Re: Ayuda!!! Sumas y restas no exactas

Muchas gracias a los 2 por sus respuestas!!!
Si me entere un poco mas de estos bugs leyendo por otros foros y demas. El problema radica en los calculos con numeros flotantes y los navegadores (en uno de esos temas me entere que el mas exacto para estos calculos es internet explorer xddd, lo que son las cosas xDDD)

Pero bueno, yo le di solución a mi problema con Ajax, tuve que usar php para realizar estos calculos y luego ya devolver el valor a la caja de texto

Derkenuke
Gracias por tu script mañana lo pruebo.


Igual mañana les dejo mi codigo de como lo solucioné por si a alguien mas le puede servir.

Gracias y saludos!!!
  #5 (permalink)  
Antiguo 03/01/2008, 16:40
Avatar de derkenuke
Colaborador
 
Fecha de Ingreso: octubre-2003
Ubicación: self.location.href
Mensajes: 2.665
Antigüedad: 20 años, 6 meses
Puntos: 45
Re: Ayuda!!! Sumas y restas no exactas

Hola de nuevo:

Cita:
Iniciado por Angel_Cruijff
Muchas gracias a los 2 por sus respuestas!!!
¿Quién es el otro?


Bueno, al grano. No es un problema símplemente de navegadores. Lo he probado en java y resulta también el error (al menos con 0.1*0.1).


Si no utilizas PHP puede que te sirva el script que te he pasado para transformar cualquier multiplicación a un conjunto de sumas, siempre dará el resultado correcto. He comprobado yo también que en PHP funciona correctamente. Y si no quieres utilizar tanta función, creo que tu solución es Math.round().

Con AJAX creo que sólo llenarías el servidor de peticiones, aumentarías la transferencia, y harías esperar inútilmente al visitante.



Un saludo
__________________
- Haz preguntas inteligentes, y obtendrás más y mejores respuestas.
- Antes de postearlo Inténtalo y Búscalo.
- Escribe correctamente tus mensajes.
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta

SíEste tema le ha gustado a 1 personas (incluyéndote)




La zona horaria es GMT -6. Ahora son las 07:19.