Float, eres problemático y Arduino lo sabe
¡Ante todo pronóstico he vuelto por aquí! No recuerdo cuando fue la última vez que escribí (Aunque sería tan sencillo como mirar la última entrada…) pero he vuelto a traerte problemas.
En este caso el problema se llama float. Los float son los números más problemáticos en los microcontroladores. Seguro que si los llamo float, no tienes ni idea de qué hablo. Pero si te digo números con coma, ya te vas centrando un poco.
Guardar la posición número 1000 no tiene problema alguno, guardar la temperatura 24.5ºC ya empieza a ser algo molesto. Veamos el por qué… (Y que se note que he vuelto! Pon algo de música para celebrarlo!)
Los tipos de variables en Arduino
Cuando programas en Arduino, quieres guardar algunas cosas para utilizar ese valor más adelante, eso se guarda en una variable. Una variable para el contador de alguna cosa, o una variable para que guarde el valor de temperatura que llega del sensor.
Normalmente estas variables se declaran con la palabra int delante. Int viene de integer (entero) y son los números enteros: 1,2,3,-4,-1,5,6,12…
También se utilizan las variables long, que son números enteros pero más largos. O los boolean que es lo que los informáticos llaman un bit ya que solo tiene dos estados: verdadero o falso.
Un conjunto de 8 bits, se llama byte y se declaran con la palabra byte en Arduino. Por último para letras, se utiliza el tipo char, de character.
Todos estos tipos de variables son inofensivos y no suponen mayor problema para Arduino o para cualquier microcontrolador en general.
El tipo que todos temen es aquel que es de coma flotante, es decir: los float.
Los float en Arduino y otros microcontroladores
Los float se utilizan para números en los que se necesita un poco más de precisión porque guardan valores de magnitudes continuas (La temperatura es una magnitud continua, el valor de un sensor de contacto es un valor de sí o no). Sus valores van desde 3.4028235E+38 hasta -3.4028235E+38, lo que es un rango bastante grande. Es por eso que ocupan 4 veces lo que ocupa un byte (32 bits).
La precisión de los valores son 6-7 dígitos decimales lo que no es lo mejor de lo mejor ya que en otros microcontroladores, utilizando la opción double puedes obtener hasta 15 dígitos de precisión (En Arduino, float y double tienen la misma precisión). Pero he aquí el problema de los double, los float y todo lo que tenga coma: su exactitud.
En las multiplicaciones todo va bien siempre, pero en el caso de divisiones te puedes encontrar cosas verdaderamente raras. Algo que puede pasar es que hagas una división dos veces y el valor no sea exactamente el mismo en los dos casos. Y no hablo de cosas raras, hablo de 8.0/4.0 que para ti da 2 pero que para Arduino va a dar 1.99, 2.01 o a saber qué.
Nota: Lo de utilizar 8.0 en lugar de 8 es porque cuando se trabaja con float, hay que utilizar floats por lo que se necesita añadirle la coma para evitar problemas de tipo de variable. Es decir 8/4 no es un float, 8.0/2, 8/2.0 y 8.0/2.0 sí lo son ya que contienen dentro un float al que se le aplica una operación. |
Otro caso de problemas con las divisiones es cuando se manejan números muy pequeños. Imaginemos que tienes que dividir entre 1024 un valor que vale 100. Y luego lo tienes que multiplicar por 100. Si lo haces lo que va a suceder es que el valor final no será el mismo que da la calculadora.
Digamos que con los números con coma, al dividir por un número tan grande, el microcontrolador se lía y los redondeos van muy a lo loco. Esto hace que al multiplicar luego por 100 el resultado sea incorrecto.
La única cura para esto es hacerlo de manera inversa. Multiplicar por 100 para tener un número bastante grande y luego dividir. Así conseguirás resultados normales. Así que como normal general aplica primero las multiplicaciones y luego las divisiones para obtener resultados más exactos con floats 😉
Información básica sobre Proteción de datos
Responsable ➥ Sergio Luján Cuenca
Finalidad ➥ Gestionar el envío de correos electrónicos con artículos, noticias y publicidad. Todo relacionado con los temas de rufianenlared.com
Legitimación ➥ Consentimiento del interesado
Destinatarios ➥ Estos datos se comunicarán a MailRelay para gestionar el envío de los correos electrónicos
Derechos ➥ Acceder, rectificar y suprimir los datos, así como otros derechos, como se explica en la política de privacidad
Plazo de conservación de los datos ➥ Hasta que se solicite la supresión por parte del interesado
Información adicional ➥ Puedes encontrarla en la política de privacidad y el aviso legal
Los bits que componen los float
Ahora veamos la forma de un elemento de coma flotante. He dicho antes que se compone de 32 bits. Un bit es un 1 o un 0 que al unirse a otros unos y ceros permite crear números. Esto es porque se utiliza la notación binaria, dónde cada 1 o 0 se multiplica por el peso que corresponde a su posición.
Es decir 100 en binario corresponde con 4 ya que el 1 en la posición 3 vale 4. Si fuese en la posición 2 valdría 2 y si fuese en la posición 4 valdría 8. ¿Ves la progresión? Cada posición vale 2 elevado a esa posición menos 1. La primera es 2 elevado a 0 que es 1. Si aparece un 1 vale 1 y si aparece un 0 vale 0.
Luego es 2 elevado a 1, si hay un 1 vale 2 y si hay un 0 vale 0. Y así así todos los valores. Pues tenemos 32 unos y ceros, pero para que el microcontrolador los pueda entender se dividen. El primer bit es el signo. Si es un 1 el signo es negativo, si es un 0 el signo es positivo. Ya sabemos si nuestro número es positivo o negativo.
Luego tenemos 8 bits que son el número antes de la coma. Si el número es 2.54, estos bits contendrían el número 2, que en binario sería 00000010. El resto de bits (los 23 restantes) forman la parte que hay después de la coma.
¿Lo he hecho bien o malamente?
Bueno, llegados a este punto debo decirte que el uso de floats es más lento como podrás entender ya. Es por eso que no se utiliza en procesos críticos. Pero críticos de verdad, si vas a automatizar un jardín o vas a hacer cosas normales en las que no corre en peligro la vida de nadie no debes de preocuparte por el uso de floats.
Si volvemos al ejemplo del 2.54, otra opción sería multiplicar todo por 100. Hacer las divisiones y multiplicaciones con números enteros y una vez finalizado todo podrías dividirlo entre 100.0 y tener el float deseado.
Y hasta aquí ha llegado lo de esta semana. Creo que he perdido la práctica a la hora de escribir, pero eso lo dejo para que me lo comentes en la sección de comentarios y decidamos si el verano me ha sentado bien o malamente XD
comienzo a pensar que al hombre del parche no le ocurrió nada en el ojo, en la imagen de arriba el parche está en el ojo izquierdo y en la imagen de abajo en el ojo derecho