División entera y escala de una entrada

0

Estoy tratando de ubicarme en la división de enteros. Estoy ingresando un número decimal entre 100 y 6300 en mi programa, luego necesito escalar este número en 100 y mostrar el resultado como un número de 6 bits.

Matemáticamente, lo que estoy tratando de hacer es:

Salida = Entrada / 100

Muy simple! Pero parece que no consigo que esto funcione en C. Estoy usando MikroC para una MCU PIC18.

Código de ejemplo:

int input;
int output;

void main(){
TRISA = 0x00;
input = 1000;//operator has input 1000
output = input/100.0;//scale input by 100
PORTA = output;//output 6-bit number
}
    
pregunta Gozmit

2 respuestas

2

En lo que a mí respecta, no hay necesidad de una división flotante aquí, si solo va a convertir el resultado en un entero y escribir en un puerto. El resultado de la división flotante se truncará para obtener un entero, por lo que puede hacer aritmética de enteros.

unsigned int input;
unsigned char output;

void main(){
  TRISA = 0x00;
  input = 1000;//operator has input 1000
  output = input/100;//scale input by 100
  PORTA = output;//output 6-bit number

  while (1);  //while away once the program is done
}

Para la independencia de la implementación, puede incluir stdint.h y usar uint8_t y uint16_t para definir output y input respectivamente, aunque eso no es necesario aquí. Si desea los beneficios de la división flotante, debe redondear .

#include <math.h>

unsigned int input;
unsigned char output;

void main(){
  TRISA = 0x00;
  input = 1000;
  output = round((double)input/100.0);  // implicit cast to uchar
  PORTA = output;

  while (1);  //while away once the program is done
}

Debo mencionar que este último enfoque es más costoso que el anterior, debido a su aritmética de punto flotante. Use esto solo si necesita la precisión adicional.

EDITAR:

Un compromiso sería agregar una compensación a input y luego dividir; esto aumenta la precisión de sus resultados al simular el redondeo con números enteros. Es mucho más eficiente que la opción de punto flotante.

unsigned int input;
unsigned char output;

void main(){
  TRISA = 0x00;
  input = 1000;
  output = (input + 50) / 100; 
  PORTA = output;

  while (1);  //while away once the program is done
}
    
respondido por el TisteAndii
1

Su código debería haber generado una gran cantidad de mensajes de advertencia, específicamente acerca de las conversiones faltantes. Su cálculo debería ser más explícito, y debe verse así:

output = (int) ((float) input / 100.0); // una operación más explícita

Sin embargo, "salida" debería haberse definido como "corto" si el resultado es solo de seis bits. Dado que "PORTA" solo tiene 8 bits y "output" es de 16 bits, el compilador probablemente almacenó el byte alto de "output" (un cero) en "PORTA" y almacenó el byte bajo (el resultado real) en la ubicación de la memoria siguiente "PORTA".

output = (short) ((float) input / 100.0); // "salida" debe ser corta

    
respondido por el Mark

Lea otras preguntas en las etiquetas