error al convertir una matriz en un entero

1

Estoy intentando enviar un número desde una PC a un PIC18f4550 como una matriz usando USART y luego convertirlo en un entero usando una rutina dentro del PIC.

El problema es que, en algunos casos, el número entero no es el mismo número que la matriz (generalmente es 1 unidad menos) como muestro en la imagen.

#include<18F4550.h>#include<math.h>#FUSESNOWDT,XT,NOPUT,NOPROTECT,NOBROWNOUT,NOLVP,NOCPD,NOWRT,NODEBUG#usedelay(clock=20000000)#users232(uart1,baud=9600)intcount[5]={0,0,0,0,0};intpulses=0;inti=0;intj=0;voidmain(){while(true){delay_ms(10);pulses=0;for(i=0;i<5;i++)//Convertsthearrayintoaninteger{pulses=pulses+count[4-i]*pow(10,i);}printf("P: %u    ",pulses);   //Prints the integer and the used array
      for(i=0; i<5; i++)
      {
         printf("%u ",count[i]);
      }
      printf("\r");
      if(count[4]<9)   //Increases the array in 1
         count[4]++;
      else
      {
         count[4]=0;
         if(count[3]<9)
            count[3]++;
         else
         {
            count[3]=0;
            if(count[2]<9)
               count[2]++;
            else
            {
               count[2]=0;
               if(count[1]<9)
                  count[1]++;
               else
               {
                  count[1]=0;
                  count[0]++;
               }
            }
         }
      }
   }
 }
    

1 respuesta

4

OK, parece que tu compilador no sigue el estándar c.

En c un int se define como al menos 16 bits. El compilador que está utilizando define un int como 8 bits. Es por eso que cuando usa un int, se ajusta a 255 (o 127 para números firmados).

Como solo usas valores sin signo, los puntos son int16 sin signo. (e ignore mis comentarios anteriores, use% lu en las llamadas a printf () ya que su compilador piensa que 16 bits es mucho)

La función pow () debería devolver un doble, sin embargo, parece que tu compilador solo admite flotadores, de cualquier manera, supongo que los errores que estás viendo están relacionados con el redondeo al volver a convertir de float / double a un entero.
Tu cálculo fue int = int + int * float, el flotante tiene prioridad sobre el int y así terminas con int = float. El compilador luego automáticamente lanza el flotador de nuevo a un int. Al hacer esto en c, el sistema siempre redondeará hacia abajo. Entonces, si el resultado fue 9.99999999 en lugar de 10 debido a errores de redondeo de punto flotante, obtienes 9 no 10.

Puedes resolver esto agregando 0.5 a cada cálculo, luego se redondeará al entero más cercano en lugar de redondearlo hacia abajo. Sin embargo, la mejor opción es probablemente evitar todas las cosas de punto flotante por completo. Hacer todo con números enteros será más rápido y más confiable.

Prueba:

pulses=0;
//Converts the array into an integer, [0] is most significant
for(i=0; i<5; i++) {
  pulses = pulses*10 + count[i];
}
    
respondido por el Andrew

Lea otras preguntas en las etiquetas