Microcontroladores PIC => Lenguaje C para microcontroladores PIC => Mensaje iniciado por: micro_pepe en 09 de Octubre de 2006, 17:27:12
Título: Resta BCD en valor absoluto
Publicado por: micro_pepe en 09 de Octubre de 2006, 17:27:12
Hola, necesito hacer una resta en BCD en valor absoluto, con este codigo me funciona si el resultado es positivo, pero no si es negativo. No se me ocurre como solucionarlo con poco codigo.
int i,Acarreo,BCD[10],RES[10]; Acarreo=0; for(i=0;i<10;i++){ if(BCD[i]<=RES[i]){ BCD[i]=(BCD[i]+10)-(RES[i]+Acarreo); Acarreo=1;} else{ BCD[i]=BCD[i]-(RES[i]+Acarreo); Acarreo=0;} } Saludos y gracias.
Título: Re: Resta BCD en valor absoluto
Publicado por: Modulay en 09 de Octubre de 2006, 18:15:15
Si no me equivoco,el resultado será negativo siempre que en la última iteración acarreo valga 1. De todas formas,al consistir tus operandos en arrays de dígitos bcd,debes pensarte el como vas a manejar los resultados que obtengas cuando la resta deba dar un valor negativo. Te explico como lo haría yo: Para detectar si el resultado es positivo ó negativo basta con mirar el valor de acarreo una vez completada la resta.Si acarreo vale 1 es que tu resultado es negativo.Ahora bien,cuando esto ocurre,el valor que te queda en el array BCD es el complemento a 10 del valor absoluto del auténtico valor que resulta de la resta.Ejemplo: Restando de forma usual : 132 - 140 = -8 Restando con tu algoritmo : 132 - 140 = 992 (acarreo=1)
O sea,que para determinar el valor negativo que buscas (-8) tendrías que restarle el 992 que obtuviste a la unidad seguida de ceros inmediatamente superior:
1000 - 992 = 8
...sin olvidar claro que esto te da el valor absoluto de un número que sabes que es negativo. Si entiendes esto ya sólo te queda pensar como realizar esta operación cuando detectes que el resultado es negativo y cómo transformar tu array para que albergue el resultado final. Cualquier cosa que no te quede clara no tienes más que preguntar,por aquí andaremos. Saludete
Título: Re: Resta BCD en valor absoluto
Publicado por: Modulay en 09 de Octubre de 2006, 22:27:44
Creo que me colé en un pequeño detalle. Si bien acarreo terminará valiendo 1 tras las 10 iteraciones cuando el resultado de la resta sea negativo,también hay combinaciones que den resultados positivos que harán que acarreo también termine con el valor 1.Un ejemplo ilustrativo sería el mismo de antes pero cambiando el orden de los operandos: 140 - 138 = 8 A partir del 4º dígito en adelante,todos son ceros,por lo que acarreo termina con el valor 1. Se me ocurre que en vez de usar el valor final de acarreo para actuar de una forma u otra lo hagas con una variable booleana.Algo así:
Código: C++
int i,Acarreo,BCD[10],RES[10];
boolean bcd_mayor = TRUE;
Acarreo=0;
for(i=0;i<10;i++){
if(BCD[i]<=RES[i]){
if(BCD[i]< RES[i]){ bcd_mayor = FALSE;}
BCD[i]=(BCD[i]+10)-(RES[i]+Acarreo);
Acarreo=1;}
else{
bcd_mayor = TRUE;
BCD[i]=BCD[i]-(RES[i]+Acarreo);
Acarreo=0;}
Asi,desde el primer dígito hasta el último y en cada iteración,la booleana te estará indicando quien es mayor de los dos. Cuando los dígitos sean iguales,dicha variable mantendrá su valor anterior,siendo los dos dígitos que la sobreescriban por última vez los que determinarán cual de los dos números es mayor.
Título: Re: Resta BCD en valor absoluto
Publicado por: micro_pepe en 10 de Octubre de 2006, 14:04:27
Gracias por la respuesta, lo tendré en cuenta, aunque estoy barajando la posibilidad de pasar a decimal uno de los operandos, (el otro de los operandos ya está en decimal) y hacer la operacion en decimal.