¿Cómo se manejan los números con punto decimal en una MCU?

7

Por favor, dígame cómo las MCU manejan números decimales como '23 .3 ',' 3.24 ', etc. ¿Cómo se almacena en un registro de memoria? Sé que tengo que usar el tipo de datos flotantes al manejar estos números durante la programación. Pero en realidad, lo que está sucediendo dentro de una MCU al manejar estos tipos. También dígame cómo las MCU sin unidad FPU manejan el tipo de datos Float.

    
pregunta 0xakhil

5 respuestas

11

Los números dentro de los microcontroladores típicos no tienen puntos decimales en absoluto. Son enteros binarios. No hay ningún decimal dentro de la máquina. El compilador o el ensamblador pueden permitirle especificar constantes de esa manera, pero se convierten a binarios antes de que la máquina los vea.

Sin embargo, puede decidir las unidades que desee para los valores enteros. Por ejemplo, suponga que quiere representar dólares dentro de un micro. No puede hacer $ 3.21 de forma nativa, pero podría hacer 321 centavos. El micro solo está operando en el valor 321, pero usted sabe que representa unidades de 1/100 dólares.

Este es solo un ejemplo para ilustrar el concepto de unidades arbitrarias. A menudo los números se representan con varios bits de fracción binarios. Es lo mismo que decir que cada cuenta representa un valor de 2 -N , donde N es el número de bits de fracción. Esta representación se llama "punto fijo". Usted decide de antemano la cantidad de resolución que necesita y pretende que hay suficientes bits a la derecha del punto binario imaginado para admitir esa resolución. Por ejemplo, digamos que necesita representar algo con al menos una resolución de 1/100. En ese caso, utilizarías al menos 7 bits de fracción desde 2 7 = 128. Eso te dará una resolución de 1/128.

La máquina no tiene idea de que esto está sucediendo. Sumará y restará estos números como enteros ordinarios, pero todo seguirá funcionando. Se vuelve un poco complicado cuando multiplicas y divides valores de puntos fijos. El producto de dos valores de punto fijo con bits de fracción N tendrá 2 bits de fracción. A veces, simplemente hace un seguimiento del hecho de que el nuevo número tiene bits de fracción 2N, o a veces puede cambiarlo en N bits para volver a la misma representación que antes.

El punto flotante es lo mismo, pero el número de bits de fracción se almacena junto con la parte entera para que este ajuste se pueda hacer en tiempo de ejecución. Realizar operaciones matemáticas en números de punto flotante puede llevar muchos ciclos. El hardware de punto flotante hace todo esto por usted para que las operaciones se completen rápidamente. Sin embargo, las mismas manipulaciones se pueden realizar en el software también. No hay ninguna razón por la que no pueda escribir una subrutina para agregar dos números de punto flotante, solo que tomaría mucho más tiempo que el hardware dedicado haciendo lo mismo.

He definido un formato de punto flotante de 3 bytes para PIC de 8 bits y he escrito un montón de rutinas para manipularlos. Los microcontroladores generalmente tratan con valores del mundo real con una precisión de 10 o 12 bits como máximo. Mi formato de punto flotante utiliza 16 bits de precisión, lo cual es suficiente para varios cálculos intermedios.

También tengo un formato de 32 bits para los PIC de 16 bits. Esto utiliza una palabra de 16 bits para la mantisa, que acelera los cálculos, ya que estos PIC pueden operar en 16 bits a la vez.

Estas rutinas se incluyen en mi versión de PIC Development Tools . Después de la instalación, mire los archivos con "fp24" en su nombre en FUENTE > Directorio PIC y "fp32f" en la FUENTE > Directorio DSPIC.

    
respondido por el Olin Lathrop
4

Aritmética de punto fijo se usa generalmente para realizar cálculos fraccionarios en MCU.

El truco es decir que (por ejemplo), los 16 bits superiores de uint32_t están antes del punto decimal y los 16 inferiores están después, es decir. El entero almacenado está en 1/2 ^ 16ths. Con algunas pequeñas advertencias, la aritmética regular "simplemente funciona".

Aquí hay una descripción general .

    
respondido por el Toby Jaffey
1

A menos que su MCU sea un DSP con multiplicador de punto flotante, todo se almacena como números de 16 bits (u 8 o 32 según su plataforma). Eso es todo lo que sabe el MCU real.

Sobre esto tienes tu código "C" y tu compilador C. El compilador "sabe" sobre varios tipos de datos como char, int's, uint's, float, doubles, etc.

La representación más común de flotadores en hardware es con un formato IEEE. Esto separa la mantisa del exponente y usa dos palabras de 16 bits para almacenar la información. Echa un vistazo a este artículo wiki sobre formatos de número IEEE.

Así que es el compilador el que sabe dónde está la mantisa y el exponente y le aplica las matemáticas. ¿Recuerda aprender sobre logaritmos? ¿Cómo hicieron las matemáticas más fáciles agregando poder cuando querías multiplicar? Bueno, el compilador c hace algo similar con los exponentes y multiplica la mantisa para calcular la respuesta. Entonces, para una multiplicación de punto flotante, el compilador creará un código de ensamblador que agrega los exponentes y realiza la multiplicación de la mantisa.

¡La MCU no sabe nada del número! justo lo que se le dice que haga, cargue una memoria en un registro, agregue una memoria al registro y establezca el indicador de acarreo si es necesario, y así sucesivamente hasta que se complete la multiplicación.

Es el compilador de C y su código que "abstrae" el concepto de números, puntos decimales, etc. de la MCU.

En una nota al margen, algunos idiomas también admiten el tipo de datos "decimal", que es útil para los sistemas financieros, no es común en las plataformas integradas, ya que los flotadores utilizan menos memoria y funcionan de manera eficiente.

    
respondido por el smashtastic
1

De la misma manera, los procesadores completos sin un fpu (la mayoría de los ARM, por ejemplo) manejan el punto flotante. Con un software fpu. Hay una biblioteca que realiza las operaciones de matemáticas / bitwise. Si recuerda hacer sumas, multiplicaciones, etc. en la escuela primaria con lápiz y papel, no cambió mucho el día que pasó de números enteros a números con un punto decimal. Hiciste los cálculos de la misma manera que solo tenías que ajustar los números para que los puntos decimales se alinearan antes de comenzar (suma y resta) o después de que terminaras (multiplicación o división). Los fpus duros y blandos no son diferentes, ajustan los bits antes y después de la operación, pero la operación es básicamente una operación de número entero.

No recuerdo exactamente dónde encontrarlo ahora, pero los instrumentos de Texas tenían un muy buen documento relacionado con sus productos DSP. Explicó su formato de punto flotante y llegó a explicar cómo funcionaban las operaciones. Su formato no tiene redondeo, ni denormales, sino infinito, silencioso y de señalización, como IEEE, por lo que es mucho más fácil de entender y mucho más rápido que los formatos IEEE. Una vez que ve ese formato en acción, ha dado su primer paso hacia el formato IEEE. El redondeo requiere cierta explicación y pensamiento, pero el resto, los conceptos básicos de signo, exponente y mantisa son los mismos.

Es muy costoso, en cuanto a recursos (memoria, flash, ciclos de cpu) el uso de bibliotecas de flotación suave y lo desaconsejaría en un sistema integrado o un microcontrolador. 12.3 y 24.5 son bastante fáciles de administrar como los enteros 123 y 245, por ejemplo, siempre que recuerde o quizás si se asegura de que todas sus matemáticas asociadas entiendan que los números se multiplican por diez y si / cuando se muestra a una usuario en esa conversión se agrega el punto decimal. Guarda toneladas de código y rendimiento. Por supuesto, la división de enteros es algo malo con los microcontroladores y los sistemas integrados, así como la mayoría de los procesadores no tienen una instrucción de división, y eso incluye la división por 10 para convertir a decimal para mostrar al usuario. Y la misma respuesta, la división que obtienes de tu código C se hace usando una biblioteca. Así que la división de punto flotante en estos sistemas es cara al cuadrado.

    
respondido por el old_timer
0

Los flotadores se almacenan en formato binario de 32 bits y el primer bit es para indicar si el flotante es un número pos / neg, los siguientes 8 bits son el exponente -127, entonces hay 23 bits que son el número completo, incluido el decimal lugar, es decir:
1 00010001 00010001000000000000000
Entonces, 1 es negativo, los siguientes 8 bits son para indicar el exponente en este caso:
0001 0001 = 17 (17-127 = -110)
Entonces la mantisa se divide:
(1+1/4+1/128)2^5

2^5 fue el movimiento del lugar decimal cuando el flotador se movió a binario. El resultado pierde algunos dígitos al convertir, pero están cerca. 1.5ex10-110
Es posible que haya cometido errores siguiendo a otros, pero esta es la idea general de cómo se guardan los flotadores en la memoria.

    
respondido por el Mike C

Lea otras preguntas en las etiquetas