2.06 Comparisons (<, <=, ==, !=), Floating-Point Epsilon & ARM Condition Codes (APSR)
Executive Summary: Exploring relational comparison operators. We demonstrate why exact equality comparisons (==) on floating-point numbers fail due to binary representation inaccuracy and how to compare using an epsilon tolerance, and inspect ARM Application Program Status Register (APSR) condition flags (N, Z, C, V).
💻 1. Annotated Source Code
#include <iostream> using namespace std; int main() { // > Greater than // < Less than // >= Greater than or equal to // <= Less than or equal to // == Equal to // != Not equal to cout << boolalpha; int a = 15; int b = 20; cout << (a < b) << endl; // equal to bool areEqual = (a == b); cout << areEqual << endl; // challenge int age = 17; cout << (age >= 21) << endl; return 0; }
📐 2. Architecture & UML Class Model
<<compilation-unit>>
RelationalEvaluator
APSR Flags (N, Z, C, V)
Attributes / Data Members
-threshold : int32_t
-currentValue : int32_t
Operations / Methods
+isEqual(a: int, b: int) : bool
+isGreater(a: int, b: int) : bool
+isLessOrEqual(a: int, b: int) : bool
📚 3. Core C++ Concepts Deep-Dive
1. Relational Operators
Relational operators (<, >, <=, >=, ==, !=) return boolean values (true / false).
2. The Floating-Point Equality Hazard
Binary floating-point numbers cannot represent decimal fractions like 0.1 exactly ($0.1 + 0.2 \ne 0.3$). Direct equality comparisons (a == b) are dangerous. Use epsilon tolerance checks: std::abs(a - b) < EPSILON.
⚡ 4. Embedded Systems & Hardware Reality
1. ARM Cortex-M Condition Flags (APSR)
The CMP instruction subtracts two operands and sets flags in the Application Program Status Register (APSR):
- Z (Zero): Set if result is zero (equality).
- N (Negative): Set if result is negative.
- C (Carry): Set on unsigned overflow/no-borrow.
- V (oVerflow): Set on signed arithmetic overflow.
💡 5. Production-Ready Embedded Refactoring
Robust floating-point and fixed-point comparison helper:
💡 Production-Ready Refactor
#include <cmath> constexpr float EPSILON = 0.0001f; constexpr bool areFloatsEqual(float a, float b) noexcept { float diff = a - b; return (diff < 0.0f ? -diff : diff) < EPSILON; }
📝 Knowledge Verification Quiz
Test your understanding of the C++ concepts and embedded microcontroller trade-offs covered in this guide. Click any option for instant feedback.
Q1. Why does the expression '0.1f + 0.2f == 0.3f' evaluate to false in C++?
Detailed Explanation:
Binary floating-point represents numbers as fractions with powers of 2 in the denominator; decimal fractions like 0.1 produce repeating binary fractions that suffer rounding truncation.
Q2. How should two floating-point sensor values be compared for equality in safety-critical firmware?
Detailed Explanation:
Comparing against an epsilon tolerance accounts for floating-point representation and calculation rounding errors.
Q3. Which ARM APSR status flag is set to 1 when a comparison (CMP R0, R1) detects two equal values?
Detailed Explanation:
CMP R0, R1 computes $R0 - R1$. If they are equal, the result is zero, setting the Z (Zero) condition flag to 1.
Q4. What is the return type of relational expressions (e.g. 5 > 3) in C++?
Detailed Explanation:
Relational operators in C++ return boolean type (
bool).