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

8

Por favor, dígame cómo manejan las MCU 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 cuando manejo estos números mientras programo. Pero en realidad lo que está sucediendo dentro de una MCU mientras se manejan estos tipos. También dígame cómo las MCU sin unidad de FPU manejan el tipo de datos Float.

0xakhil
fuente

Respuestas:

13

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

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

Ese es solo un ejemplo para ilustrar el concepto de unidades arbitrarias. A menudo, los números se representan con varios bits de fracción binaria. 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 por adelantado cuánta resolución necesita y finge que hay suficientes bits a la derecha del punto binario imaginado para admitir esa resolución. Por ejemplo, supongamos que necesita representar algo con al menos una resolución de 1/100. En ese caso, usarías al menos 7 bits de fracción, ya que 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 sigue funcionando. Se vuelve un poco complicado cuando multiplica y divide valores de puntos fijos. El producto de dos valores de punto fijo con N bits de fracción tendrá 2N bits de fracción. A veces solo hace un seguimiento del hecho de que el nuevo número tiene 2N bits de fracción, o a veces puede cambiarlo a la derecha por 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 realizar en tiempo de ejecución. Realizar operaciones matemáticas en números de coma flotante puede tomar varios 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 también en el software. No hay ninguna razón por la que no pueda escribir una subrutina para agregar dos números de coma flotante, solo que llevarí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 usualmente manejan valores del mundo real con una precisión de 10 o 12 bits como máximo. Mi formato de coma flotante usa 16 bits de precisión, lo cual es lo suficientemente bueno para varios cálculos intermedios.

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

Estas rutinas están incluidas en mi versión de Herramientas de desarrollo PIC . Después de la instalación, mire los archivos con "fp24" en su nombre en el directorio SOURCE> PIC y "fp32f" en el directorio SOURCE> DSPIC.

Olin Lathrop
fuente
Estándar de punto flotante También hay un estándar de IBM que simplemente se equivocó con el sesgo.
NickHalden
4

La 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 a uint32_testá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 .

Toby Jaffey
fuente
un voto de mi parte para ese enlace "Descripción general".
0xakhil
3

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

Encima de esto tienes tu código "C" y tu compilador de C. El compilador "sabe" acerca de varios tipos de datos como char, int's, uint's, flotantes, dobles, etc.

La representación más común de flotantes 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úmeros IEEE.

Entonces es el compilador el que sabe dónde está la mantisa y el exponente y le aplica las matemáticas. ¿Recuerdas haber aprendido sobre logaritmos? ¿Cómo facilitaron las matemáticas al agregar potencia cuando querías multiplicar? bueno, el compilador de c hace algo similar con los exponentes y multiplica la mantisa para calcular la respuesta. Entonces, para una multiplicación de coma flotante, el compilador creará un código ensamblador que agrega los exponentes y realiza la multiplicación de mantisa.

¡El MCU no sabe nada del número! justo lo que se le pide que haga, cargue una memoria en un registro, agregue una memoria al registro y configure 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 el 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 usan menos memoria y funcionan de manera eficiente.

aplastante
fuente
1

De la misma manera, los procesadores completos sin una fpu (la mayoría de los ARM, por ejemplo) manejan el punto flotante. Con un software fpu. Hay una biblioteca que realiza las operaciones matemáticas / bit a bit. Si recuerda haber sumado, multiplicado, etc. en la escuela primaria con lápiz y papel, no cambió mucho el día en 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 terminar (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 coma flotante y llegó a explicar cómo funcionaban las operaciones. Su formato no tiene redondeo y valores denormales e infinito y canales silenciosos y de señalización como IEEE, por lo que es mucho más fácil de entender y significativamente más rápido que los formatos IEEE. Una vez que veas ese formato en acción, has dado tu primer paso hacia el formato IEEE. El redondeo requiere alguna 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) usar bibliotecas de flotación suave y lo desaconsejaría en un sistema embebido o microcontrolador. 12.3 y 24.5 son bastante fáciles de administrar como los enteros 123 y 245, por ejemplo, siempre que recuerde o tal vez si se asegura de que todas sus matemáticas asociadas comprendan que todos los números se multiplican por diez y si / cuando se muestra en un usuario en esa conversión agrega el punto decimal. Ahorra 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 entre 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.

viejo contador de tiempo
fuente
0

Los flotantes 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, luego hay 23 bits que son el número completo, incluido el decimal, es decir :
1 00010001 00010001000000000000000
Entonces 1 es que 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^5fue 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 al seguir a otros, pero esta es la idea general de cómo se guardan los flotadores en la memoria.

Mike C
fuente
2
Esta publicación puede contener rastros de información, pero está oculta en algún muro de texto de mensaje de chat sin formato. Cambio de pila no es Facebook, así que por favor trate de usar un lenguaje más profesional y por favor utilizan las herramientas de formato disponibles para hacer legible la información, a partir de los párrafos.
tubería