Detectando desbordamiento con C18

7

Estoy implementando una calculadora en un microcontrolador que se controla a través del puerto serie. Por ejemplo, enviaría 1234*5678= y respondería con 7006652\r\n . He escrito el código para esto usando el compilador C18.

Cuando envío 123456*789123= , recibo la respuesta 2932688576 , que es incorrecta. La respuesta correcta habría sido 97421969088 , pero eso desborda un unsigned long .

No quiero aumentar el límite de desbordamiento, pero me gustaría tener una manera de verificar si ha habido un desbordamiento. En ASM, eso sería posible al verificar el bit relevante en el registro de ESTADO, sin embargo, con C, este bit se borraría antes de que pudiera leerlo, ¿no?

Lo mejor sería una solución general para ver si ha ocurrido un desbordamiento.

    
pregunta Keelan

2 respuestas

3

Puede haber trucos relacionados con el registro de ESTADO pero el siguiente código genérico (no probado) es algo que pensé para verificar el número de bits necesarios para representar cada entrada realizando operaciones repetidas de desplazamiento de bits a la derecha hasta que el valor esté vacío.

Luego, sumando los dos resultados, debería poder calcular si la salida desbordará los 32 bits.

unsigned long a = 123456;
unsigned long b = 789123;

int calc_bit_size(unsigned long v)
{
    int bit_count = 0;
    while (v > 0)
    {
        bit_count++;
        v >>= 1;
    }
    return bit_count;
}

if (calc_bit_size(a) + calc_bit_size(b) > 32)
   printf("Overflow!")
else
   printf("%lu", a * b);
    
respondido por el PeterJ
2

Simplemente permita que el resultado interno sea tan ancho como la suma del ancho de los operandos, y luego verifique que el resultado no sea más alto que el permitido externamente. Si el PIC18 tiene un multiplicador de hardware, esto no es realmente costoso desde el punto de vista computacional y es completamente exacto, a diferencia del método para determinar la suma de la posición del dígito no cero más significativo de los operandos.

Consulte la página 174 del documento en enlace

    
respondido por el apalopohapa

Lea otras preguntas en las etiquetas