Ver Mensaje Individual
  #7 (permalink)  
Antiguo 12/10/2012, 05:04
Avatar de emprear
emprear
Colaborador
 
Fecha de Ingreso: junio-2007
Ubicación: me mudé
Mensajes: 8.388
Antigüedad: 17 años, 5 meses
Puntos: 1567
Respuesta: Error al restar enteros de mas de 17 caracteres

Cita:
Iniciado por furoya Ver Mensaje
Estaba pensando ... si solamente es para hacer restas, se puede hacer a lo bruto: restando dígito por dígito hasta terminar.
¿Cuanto tiempo le puede llevar a un microprocesador hacer esta cuenta?


Este ejemplo se llama "Tengo mil cosas pendientes, pero no tengo ganas de hacerlas" y es perfectible, claro, pero si le quitamos los comentarios, las alertas y pulimos los métodos que se pueden resumir un poco más (éste es didáctico, así que está bastante explayado), seguro que ocupa menos espacio que esas libraries.

Código:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" 
"http://www.w3c.org/TR/1999/REC-html401-19991224/loose.dtd">
<html>
<head>
<meta http-equiv=Content-Type content="text/html; charset=utf-8">
<title>RESTA NÚMEROS LARGOS EN JAVASCRIPT.</title>
<script type="text/javascript">
var minuendo = 185966666666645500;
var sustraendo = 85966666666645600;
var diferencia; 
	alert(minuendo + "\r\n" + sustraendo)
var alfa = minuendo.toString();
var bravo = sustraendo.toString();
var charly = [];
var delta = 0;
var signo = 1;

function resta(){


/* SI EL MINUENDO ES MAYOR QUE EL SUSTRAENDO, LOS INVIERTE PARA RESTARLOS, 
Y 'GRABA' EN signo QUE EL RESULTADO SERÁ NEGATIVO */

if(minuendo < sustraendo){
var temp = alfa;
alfa = bravo;
bravo = temp;
signo = -1
//	alert(alfa + "\r\n" + bravo)
}


/* SI alfa ES MAS LARGA QUE bravo , O V.V., RELLENA LA CADENA MÁS CORTA 
CON CEROS AL COMIENZO*/

if(alfa.length > bravo.length){
while(bravo.length < alfa.length){
bravo = "0" + bravo;
}}
else if(bravo.length > alfa.length){
while(alfa.length < bravo.length){
alfa = "0" + alfa;
}}

//	alert(alfa + "\r\n" + bravo)


/* CONVIERTE LAS CADENAS EN ARRAY Y LES INVIERTE EL ORDEN (POR COMODIDAD) */

alfa = alfa.split("").reverse();
bravo = bravo.split("").reverse();

//	alert("reverse \r\n" + alfa + "\r\n" + bravo)


/* RESTA UNO A UNO LOS ELEMENTOS DE alfa A LOS DE bravo CONVERTIDOS A NUMÉRICO; 
Y AGREGA CADA RESULTADO A UN NUEVO ARRAY charly */

for(i=0; i<alfa.length; i++){
charly[i] = (parseInt(alfa[i]) - parseInt(bravo[i]));
//	alert("Agrega al array "+parseInt(alfa[i])+" - "+parseInt(bravo[i])+" \r\ncharly[" + i +"]: "+ charly[i])

}

//	alert("charly= ["+charly+"]")


/* BUSCA SI ALGUNO RESULTÓ NEGATIVO, Y LO CONVIERTE A SU DIFERENCIA DE 10. 
AL SIGUIENTE ELEMENTO EN EL ORDEN (SI EXISTE, Y NO ESTÁ undefined) le resta 1 
ANTES DE HACER LA SIGUIENTE VUELTA DEL BUCLE for  */

for(i=0; i<charly.length; i++){
if(charly[i] != Math.abs(charly[i])){
charly[i] = 10 + charly[i];

//	alert("(antes de undefined) charly["+i+"] = "+charly[i]*1+"")

if(charly[i+1] != undefined) {
charly[i+1] = charly[i+1] - 1
};
//	alert("En charly[" + (i+1) +"] " + charly[i+1])
//	alert("charly cambia cuando hay negativos ["+(i+1)+"]\r\n" + charly)
}

}


/* VUELVE LOS ELEMENTOS DEL ARRAY A SU ORDENAMIENTO NATURAL, 
LOS JUNTA EN UNA MISMA CADENA, LOS CONVIERTE A NÚMERO Y LOS MULTIPLICA POR signo 
PARA HACERLO NEGATIVO SI ES QUE AL COMIENZO INVIRTIÓ LOS TÉRMINOS */

diferencia = Number(charly.reverse().join("")) * signo;

	prompt("diferencia ", diferencia)
}

onload = resta;
</script>


</head>
<body><pre>

var minuendo =     185966666666645500;
var sustraendo =    85966666666645600;
var diferencia; //  99999999999999900

0,0,5,5,4,6,6,6,6,6,6,6,6,6,9,5,8,1
0,0,6,5,4,6,6,6,6,6,6,6,6,6,9,5,8,0

0,0,-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1

99999999999999900
----


var minuendo =   158888888888888500;
var sustraendo = 158888888888888600;
var diferencia; //             -100

0,0,6,8,8,8,8,8,8,8,8,8,8,8,8,8,5,1
0,0,5,8,8,8,8,8,8,8,8,8,8,8,8,8,5,1

0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0

100
-100
----

var minuendo =   185966666666645700;
var sustraendo = 185966666666645600;
var diferencia; //              100

0,0,7,5,4,6,6,6,6,6,6,6,6,6,9,5,8,1
0,0,6,5,4,6,6,6,6,6,6,6,6,6,9,5,8,1

0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0

100

</pre></body>
</html>
Bueno, ahora se me hizo tarde, y me voy a dormir.
Así que dejo lo que tenía pendiente, para mañana.

Impresionante @furoya, una muestra más del "ingenio criollo", mi primera exclamación fué:
"Dibuje Román, dibuje..."

Esperamos por

BigNumber.set(n: Object): BigNumber

Sets the value of the object with the specified number.

n accepts string, number or a BigNumber


BigNumber.add(n: Object): BigNumber

Does the sum.

n accepts string, number or a BigNumber


BigNumber.subtract(n: Object): BigNumber

Does the subtration.

n accepts string, number or a BigNumber


BigNumber.multiply(n: Object): BigNumber

Does the multiplication.

n accepts string, number or a BigNumber

BigNumber.divide(n: Object): BigNumber

Does the division.

n accepts string, number or a BigNumber

BigNumber.mod(n: Object): BigNumber

Does the division and returns the remainder.

n accepts string, number or a BigNumber


BigNumber.pow(n: Object): BigNumber

Does the power.

n accepts string, number or a BigNumber


BigNumber.compare(n: Object): BigNumber

Compares the numbers and returns -1 if "n" is higher, 0 if they are equal and 1 if "n" is lower.

n accepts string, number or a BigNumber


BigNumber.negate(n: Object): BigNumber

Returns "-number".

n accepts string, number or a BigNumber


BigNumber.abs(n: Object): BigNumber

Returns the modulus of the number.

n accepts string, number or a BigNumber


BigNumber.intPart(n: Object): BigNumber

Returs the integer part of the number.

n accepts string, number or a BigNumber


BigNumber.round(void): void
Forces the rounding of the number.


__________________
La voz de las antenas va, sustituyendo a Dios.
Cuando finalice la mutación, nueva edad media habrá
S.R.