Autor Tema: Error con operacion de enteros con signo  (Leído 1844 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado Medusa

  • PIC18
  • ****
  • Mensajes: 252
Error con operacion de enteros con signo
« en: 07 de Julio de 2021, 22:19:21 »
Hola a todos, estoy usando el pic18f4620 y el compilador ccs V4.074, tengo una variable que lo leo desde un array cuyo valor es -77, cuando uso esta variable a hacer una operación de multiplicación y suma obtengo como resultado 50, pero cuando hago la misma operación pero en lugar de usar la variable uso una constante de valor -77 el resultado que obtengo es 18, por que?, cual es mi error?

Aquí esta mi código:
Código: [Seleccionar]
#include <18F4620.h>
#fuses HS,WDT32768,PROTECT,NOLVP,NOBROWNOUT
#use delay(clock=20MHz)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)// RS232 Estándar

int8 myCSQValue;
signed int8 myRSSIValue8;
signed int16 myRSSIValue16;
int16 myRSSIValuex;
char Buffer_ValRSSI[5];

signed int8 valueRSSI[]={-113,-110,-109,-107,-105,-103,-101,-99,-97,-95,-93,-91,-89,-87,-85,-83,-81,-79,-77,-75,-73,-71,-69,-67,-65,-63,-61,-59,-57,-55,-53}; 

void main(){
myCSQValue = 18;
myRSSIValue8 = valueRSSI[myCSQValue];

myRSSIValue16 = ((4*(myRSSIValue8)) + 452)*0.125; // Using a variable
printf("myRSSIValue16:%04Ld\r\n",myRSSIValue16);

myRSSIValue16 = ((4*(-77)) + 452)*0.125;        // Using a constant
printf("myRSSIValue16:%04Ld\r\n",myRSSIValue16);

while (TRUE);
}
« Última modificación: 07 de Julio de 2021, 23:02:02 por Medusa »

Desconectado Eduardo2

  • PIC24H
  • ******
  • Mensajes: 1004
Re:Error con operacion de enteros con signo
« Respuesta #1 en: 07 de Julio de 2021, 23:23:08 »
Hola a todos, estoy usando el pic18f4620 y el compilador ccs V4.074, tengo una variable que lo leo desde un array cuyo valor es -77, cuando uso esta variable a hacer una operación de multiplicación y suma obtengo como resultado 50, pero cuando hago la misma operación pero en lugar de usar la variable uso una constante de valor -77 el resultado que obtengo es 18, por que?, cual es mi error?
....

Overflow.   

Cuando hacés (4*(myRSSIValue8))    con -77 el resultado correcto es -308, pero como el valor temporal es de 8 bits, se pierde el 9no bit y te queda -52  , luego (-52+452)*.125 = 50

En cambio cuando usas una constante, el compilador evalúa la expresión y asigna directamente 18 a myRSSIValue8

Lo que tenés que hacer es ayudar al compilador escribiendo una expresión equivalente que evite overflow, no confiar en compilaciones milagrosas.

Código: [Seleccionar]
#include <18F4620.h>
#fuses HS,WDT32768,PROTECT,NOLVP,NOBROWNOUT
#use delay(clock=20MHz)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)// RS232 Estándar

int8 myCSQValue;
signed int8 myRSSIValue8;
signed int16 myRSSIValue16;
int16 myRSSIValuex;
char Buffer_ValRSSI[5];

signed char valueRSSI[]={-113,-110,-109,-107,-105,-103,-101,-99,-97,-95,-93,-91,-89,-87,-85,-83,-81,-79,-77,-75,-73,-71,-69,-67,-65,-63,-61,-59,-57,-55,-53};

void main(){
myCSQValue = 18;
myRSSIValue8 = valueRSSI[myCSQValue];

myRSSIValue16 = ((4*(myRSSIValue8)) + 452)*0.125; // Using a variable
printf("myRSSIValue16:%04Ld\r\n",myRSSIValue16);

myRSSIValue16 = ((4*(-77)) + 452)*0.125;         // Using a constant
printf("myRSSIValue16:%04Ld\r\n",myRSSIValue16);

//***************************************************************************
myRSSIValue16 = (myRSSIValue8 + 113)/2  ;          // Using common sense
printf("myRSSIValue16:%04Ld\r\n",myRSSIValue16);
//***************************************************************************

while (TRUE);
}


Otra opción es forzar a que  un resultado temporal de determinado tipo.

Como ser escribiendo:  myRSSIValue16 = ((4L*(myRSSIValue8)) + 452)*0.125;

Pero eso es 3 veces mas lento que: myRSSIValue16 = (myRSSIValue8 + 113)/2  ;
« Última modificación: 07 de Julio de 2021, 23:36:10 por Eduardo2 »

Desconectado Medusa

  • PIC18
  • ****
  • Mensajes: 252
Re:Error con operacion de enteros con signo
« Respuesta #2 en: 08 de Julio de 2021, 20:08:15 »
Eduardo2, Gracias, excelente explicación  ((:-))


 

anything