Arduino and MicroPython Floating-Point Numbers Sketch
Floating-point numbers are essential for handling decimal values in Arduino and MicroPython programming. However, due to their inherent approximation nature, comparing them directly for equality can be problematic. This section explores how to effectively use and compare floating-point numbers in your sketches.
What We Will Learn in This Section
- Declaring and manipulating floating-point variables.
- Challenges with comparing floating-point values.
- Implementing a solution using tolerance checks.
Why Is This Lesson Important to You?
Understanding the behaviour of floating-point numbers helps ensure accurate calculations and condition checks in Arduino projects, preventing unexpected errors.
Components List
Arduino and MicroPython for ESP32" is your go-to guide for mastering ESP32 projects with clear examples and practical code. For free reading, visit Mechatronics Lab and grab your copy
Circuit Diagram (With Connection)
Not applicable for this topic.
Arduino Code
float value = 1.1;
void setup() {
Serial.begin(9600);
}
void loop() {
value = value - 0.1;
if (value == 0) {
Serial.println("The value is exactly zero");
} else if (almostEqual(value, 0)) {
Serial.print("The value ");
Serial.print(value, 7); // Print to 7 decimal places
Serial.println(" is almost equal to zero, restarting countdown");
value = 1.1;
} else {
Serial.println(value);
}
bool almostEqual(float a, float b) {
const float DELTA = 0.00001; // Maximum difference to be almost equal
if (a == 0) return fabs(b) <= DELTA;
if (b == 0) return fabs(a) <= DELTA;
return fabs((a - b) / max(fabs(a), fabs(b))) <= DELTA;
}
Here’s an explanation of the code:
1. Variable Declaration
float value = 1.1;
2. Setup Function
void setup() { Serial.begin(9600);}
3. Loop Function
void loop() { value = value — 0.1;
- if (value == 0): Checks if value is exactly zero. If true, it prints “The value is exactly zero”.
- else if (almostEqual(value, 0)): If value is not exactly zero, this condition checks if value is “almost equal” to zero by calling the almostEqual() function. If true, it prints the value to 7 decimal places and resets value to 1.1.
- else: If neither condition is true, it simply prints the current value.
4. Conditional Statements
if (value == 0) { Serial.println(“The value is exactly zero”);} else if (almostEqual(value, 0)) { Serial.print(“The value “); Serial.print(value, 7); // Print to 7 decimal places Serial.println(“ is almost equal to zero, restarting countdown”); value = 1.1;} else { Serial.println(value);}
- almostEqual(float a, float b): This function checks if two floating-point numbers a and b are nearly equal.
- const float DELTA = 0.00001;: Defines a small threshold value (DELTA) that determines how close two numbers must be to be considered “almost equal.”
- fabs(): This function returns the absolute value of a floating-point number.
- if (a == 0) return fabs(b) <= DELTA;: If a is zero, checks if b is within the threshold.
- if (b == 0) return fabs(a) <= DELTA;: If b is zero, checks if a is within the threshold.
- return fabs((a — b) / max(fabs(a), fabs(b))) <= DELTA;: For non-zero values, it compares the relative difference between a and b to the threshold DELTA.
5. The almostEqual Function
bool almostEqual(float a, float b) { const float DELTA = 0.00001; // Maximum difference to be almost equal if (a == 0) return fabs(b) <= DELTA; if (b == 0) return fabs(a) <= DELTA; return fabs((a — b) / max(fabs(a), fabs(b))) <= DELTA;}
MicroPython
import time
import math
value = 1.1
def almost_equal(a, b, delta=0.00001):
if a == 0:
return abs(b) <= delta
if b == 0:
return abs(a) <= delta
return abs((a - b) / max(abs(a), abs(b))) <= delta
while True:
value -= 0.1
if value == 0:
print("The value is exactly zero")
elif almost_equal(value, 0):
print(f"The value {value:.7f} is almost equal to zero, restarting countdown")
value = 1.1
else:
print(value)
time.sleep(0.25)
Here’s an explanation of the code:
1. Importing Modules
import timeimport math
2. Variable Declaration
value = 1.1
- def almost_equal(a, b, delta=0.00001):: Defines a function almost_equal that checks if two floating-point numbers a and b are nearly equal, within a small threshold (delta).
- delta=0.00001: This sets the default value of delta to 0.00001, representing the maximum difference for the numbers to be considered almost equal.
- if a == 0:: If a is zero, the function checks if b is within the threshold.
- if b == 0:: If b is zero, the function checks if a is within the threshold.
- return abs((a — b) / max(abs(a), abs(b))) <= delta: For non-zero values, the function calculates the relative difference between a and b and checks if it’s within the threshold delta.
3. Defining the almost_equal Function
def almost_equal(a, b, delta=0.00001): if a == 0: return abs(b) <= delta if b == 0: return abs(a) <= delta return abs((a — b) / max(abs(a), abs(b))) <= delta
4. Main Loop
while True: value -= 0.1
- if value == 0:: Checks if value is exactly zero. If true, prints “The value is exactly zero.”
- elif almost_equal(value, 0):: If value is not exactly zero, this condition checks if value is “almost equal” to zero using the almost_equal function. If true, it prints the value to 7 decimal places and resets value to 1.1.
- else:: If neither condition is true, it simply prints the current value.
5. Conditional Statements
if value == 0: print(“The value is exactly zero”)elif almost_equal(value, 0): print(f”The value {value:.7f} is almost equal to zero, restarting countdown”) value = 1.1else: print(value)
6. Delay
time.sleep(0.25)
Summary
- Precision Issues: Floating-point numbers are approximations. Precision issues can arise, especially with repetitive calculations.
- Comparison Challenges: Use tolerance-based methods to compare floating-point numbers.
- Tolerance Setting: Adjust the delta value for your application’s needs.
- Application Context: Understand the context and constraints of floating-point operations.
- Microcontroller Constraints: Efficient handling of floating-point operations is crucial due to limited resources.
Originally published at https://www.hackster.io.