¿Por qué el tipo de datos flotante no es exacto en un STM32?

2

Estoy usando STM32F103C8T6 y mi compilador es KEIL 5. He escrito un programa simple para verificar algo pero descubrí un punto interesante. Cuando descargo el programa a la MCU, aaa y bbb tienen que ser 12.56 y 62.8 , pero cuando depuro el programa en la MCU, los valores iniciales de estas variables se convierten en estos: aaa=12.5600004 y %código%. el programa:

#include "stm32f10x.h"
float aaa=12.56,bbb;

int main(void)
{
    bbb=aaa*5;
    while(1){}
}

También ten en cuenta que si cambio bbb=62.8000031 a float , funciona sin problemas.

    
pregunta xerxes

3 respuestas

4

Los números de punto flotante se representan como una suma de fracciones binarias por una potencia de dos. En los números de punto flotante IEEE-754 de precisión simple, las fracciones varían de \ $ 1 / {2 ^ 0} \ $ a \ $ 1/2 ^ {23} \ $ y las potencias de dos varían de \ $ 2 ^ {- 126} \ $ a \ $ 2 ^ {127} \ $. Por ejemplo:

$$ 12 = \ left (\ frac 1 1 + \ frac 1 2 \ right) \ cdot 2 ^ 3 = 1.5 \ cdot 8 = 12 $$ $$ 0.5 = \ left (\ frac 1 1 \ right) \ cdot 2 ^ {- 1} = 1 \ cdot \ frac 1 2 = 0.5 $$ $$ 12.5 = \ left (\ frac 1 1 + \ frac 1 2 + \ frac 1 {16} \ right) \ cdot 2 ^ 3 = 1.5625 \ cdot 8 = 12.5 $$ $$ 62 = \ left (\ frac 1 1 + \ frac 1 2 + \ frac 1 4 + \ frac 1 8 + \ frac 1 {16} \ right) \ cdot 2 ^ 5 = 1.9375 \ cdot 32 = 62 $$

Pero 0.06 y 0.8 no se pueden representar uniformemente de esta manera, al igual que \ $ 1/3 \ $ no se puede representar como una suma de fracciones decimales:

$$ \ frac 1 3 \ approx \ left (\ frac 3 {10} + \ frac 3 {100} + \ frac 3 {1000} + \ frac 3 {10000} + \ cdots \ right) \ approx 0.33333 \ dots $$

$$ 0.06 \ approx \ left (\ frac 1 1 + \ frac 1 2 + \ frac 1 4 + \ frac 1 8 + \ frac 1 {32} + \ frac 1 {128} + \ frac 1 {256} + \ frac 1 {512} + \ frac 1 {16384} + \ frac 1 {65536} + \ frac 1 {1048576} + \ frac 1 {2097152} + \ frac 1 {4194304} + \ frac 1 {8388608} \ derecha) \ cdot 2 ^ {- 5} \ approx 1.91999995708465576171875 \ cdot \ frac 1 {32} \ approx 0.0599999986588954925537109375 $$

Las representaciones decimales pueden variar de un sistema a otro. No voy a pasar mucho tiempo escribiendo más ejemplos, porque espero que ya tengas la idea. Lo importante es que los números de punto flotante son números racionales binarios , ¡aunque pones números racionales decimales en tu código fuente!

Los números de punto flotante son aproximados. Si necesita representar valores exactos, utilice números enteros o otra alternativa . Si no sabe si necesita punto flotante, es probable que no lo haga.

Para obtener más información, he encontrado que la Guía de punto flotante es más fácil de leer que ensayo de Goldberg , pero ambos son valiosos.

    
respondido por el Adam Haun
3

Los comentarios cubren lo básico, pero para una comprensión completa de lo que está sucediendo, recomiendo que vas a tener ¡Pensar! que es una serie de artículos.

En resumen, los flotantes / dobles son aproximaciones porque tienen que comprimir una cantidad infinita de valores en una representación de tamaño fijo, por lo que siempre habrá errores de aproximación. Para no sorprenderse por cómo y cuándo aparecen esos errores, debe comprender completamente cómo funcionan los flotadores.

Los artículos no solo hacen un buen trabajo al describir los principios, sino que se abren con una excelente introducción:

  

El dragón del error numérico no se despierta a menudo de su sueño, pero si se le acerca de manera incauta, ocasionalmente infligirá un daño catastrófico en los cálculos incautos del programador.

     

Tanto es así que algunos programadores, después de haberlo encontrado por casualidad en los bosques de aritmética de punto flotante IEEE 754, aconsejan a sus compañeros que no viajen en esa tierra justa.

     

En esta serie de artículos exploraremos el mundo de la computación numérica, contrastando la aritmética de punto flotante con algunas de las técnicas que se han propuesto como reemplazos más seguros. Aprenderemos que el territorio del dragón es muy extenso y que, en general, debemos andar con cuidado si tememos su atención devastadora.

    
respondido por el whatsisname
2

Hay una nota de la aplicación de STMicroelectronics, " AN4044 Nota de aplicación Uso de unidad de punto flotante (FPU) con microcontroladores STM32F405 / 07xx y STM32F415 / 417xx ". No creo que su STM32F103C8T6 tenga una unidad de punto flotante de hardware (FPU), pero sigue siendo una lectura interesante.

Todos los procesadores ARM, así como prácticamente todos los demás microprocesadores / microcontroladores actuales, utilizan un estándar llamado IEEE 754-1985 para representar números de punto flotante. Fue adoptado en 1985 y su primer uso en una FPU de hardware fue el chip 8087 de Intel, que fue un complemento del 8086. (El estándar original en realidad fue reemplazado por uno más nuevo llamado IEEE-2008, que es compatible con versiones anteriores). )

Los dos formatos principales int. IEEE estándar son 32 bits (llamado flotante en el lenguaje C) y 64 bits (llamado doble en C):

(Estafiguraestáadaptadadelanotadelaaplicaciónalaquehicereferenciaanteriormente)

Antesde1985,larepresentacióndelosnúmerosdepuntoflotantevariabadeunfabricanteaotro,porejemplo,losmainframesIBM360introducidosenladécadade1960teníanunformatosimilar,peroelexponenteenlarepresentacióndepuntoflotantedeprecisiónsimpleerade7bitsenlugarde8,ylaparteenterasinsignoerade24bitsenlugarde23.Asíquetendríaunbitmásderesolución,perosolounrangodeexponentede-62,+63enlugarde-126,+127.ElformatodelEquipoDigitalVAX-11era realmente extraño .

Otros han incluido un montón de cálculos matemáticos para mostrar la imprecisión de varios números de punto flotante, pero solo de forma intuitiva, si observa solo la parte de entero de 23 bits de un flotador, más el signo de 1 bit, y una correspondiente Entero con signo de 24 bits que tiene un valor máximo de ± 10 \ $ ^ {23} \ $, o ± 8388608, y alinear ese valor con uno de sus flotadores de precisión única,

    8388608
 12.5600004

verá que la precisión es aproximadamente la misma. Estoy seguro de que todos los expertos en matemáticas están gimiendo en este momento, solo trato de mostrar cómo se ve esto desde un nivel de 50,000 pies. De todos modos me ayudó a visualizarlo.

    
respondido por el tcrosley

Lea otras preguntas en las etiquetas