Coming Soon

This lesson is currently being developed

Relational operators and floating point comparisons

Master comparison operators and floating-point comparisons.

Operators
Chapter
Beginner
Difficulty
40min
Estimated Time

What to Expect

Comprehensive explanations with practical examples

Interactive coding exercises to practice concepts

Knowledge quiz to test your understanding

Step-by-step guidance for beginners

Development Status

In Progress

Content is being carefully crafted to provide the best learning experience

Preview

Early Preview Content

This content is still being developed and may change before publication.

6.7 — Relational operators and floating point comparisons

In this lesson, you'll learn about relational (comparison) operators, understand how they work with different data types, and discover the critical issues with floating-point comparisons and how to handle them correctly.

What are relational operators?

Relational operators compare two values and return a boolean result (true or false). They're essential for decision making, loops, and conditional logic in your programs.

C++ provides six relational operators:

  • == (equal to)
  • != (not equal to)
  • < (less than)
  • > (greater than)
  • <= (less than or equal to)
  • >= (greater than or equal to)

These operators work with all fundamental data types and return boolean values that can be used in conditional statements, assignments, and other logical operations.

Basic relational operations

Equality operators (== and !=)

#include <iostream>

int main()
{
    int a = 10;
    int b = 10;
    int c = 15;
    
    // Equality comparisons
    std::cout << "Equality comparisons:" << std::endl;
    std::cout << "a == b: " << (a == b) << std::endl;  // true (1)
    std::cout << "a == c: " << (a == c) << std::endl;  // false (0)
    std::cout << "a != b: " << (a != b) << std::endl;  // false (0)
    std::cout << "a != c: " << (a != c) << std::endl;  // true (1)
    
    // Character comparisons
    char ch1 = 'A';
    char ch2 = 'A';
    char ch3 = 'B';
    
    std::cout << "\nCharacter comparisons:" << std::endl;
    std::cout << "ch1 == ch2: " << (ch1 == ch2) << std::endl;  // true
    std::cout << "ch1 == ch3: " << (ch1 == ch3) << std::endl;  // false
    
    // Boolean comparisons
    bool flag1 = true;
    bool flag2 = false;
    bool flag3 = true;
    
    std::cout << "\nBoolean comparisons:" << std::endl;
    std::cout << "flag1 == flag3: " << (flag1 == flag3) << std::endl;  // true
    std::cout << "flag1 != flag2: " << (flag1 != flag2) << std::endl;  // true
    
    return 0;
}

Output:

Equality comparisons:
a == b: 1
a == c: 0
a != b: 0
a != c: 1

Character comparisons:
ch1 == ch2: 1
ch1 == ch3: 0

Boolean comparisons:
flag1 == flag3: 1
flag1 != flag2: 1

Ordering operators (<, >, <=, >=)

#include <iostream>

int main()
{
    int x = 15;
    int y = 10;
    int z = 15;
    
    // Ordering comparisons
    std::cout << "Ordering comparisons:" << std::endl;
    std::cout << "x > y: " << (x > y) << std::endl;    // true
    std::cout << "x < y: " << (x < y) << std::endl;    // false
    std::cout << "x >= z: " << (x >= z) << std::endl;  // true (equal values)
    std::cout << "x <= z: " << (x <= z) << std::endl;  // true (equal values)
    std::cout << "y < x: " << (y < x) << std::endl;    // true
    std::cout << "y <= x: " << (y <= x) << std::endl;  // true
    
    // Character ordering (ASCII values)
    std::cout << "\nCharacter ordering:" << std::endl;
    std::cout << "'A' < 'B': " << ('A' < 'B') << std::endl;    // true
    std::cout << "'a' > 'A': " << ('a' > 'A') << std::endl;    // true (lowercase has higher ASCII)
    std::cout << "'5' > '1': " << ('5' > '1') << std::endl;    // true (digit comparison)
    
    // Demonstrating ASCII values
    std::cout << "\nASCII values:" << std::endl;
    std::cout << "'A' = " << static_cast<int>('A') << std::endl;  // 65
    std::cout << "'a' = " << static_cast<int>('a') << std::endl;  // 97
    std::cout << "'0' = " << static_cast<int>('0') << std::endl;  // 48
    
    return 0;
}

Output:

Ordering comparisons:
x > y: 1
x < y: 0
x >= z: 1
x <= z: 1
y < x: 1
y <= x: 1

Character ordering:
'A' < 'B': 1
'a' > 'A': 1
'5' > '1': 1

ASCII values:
'A' = 65
'a' = 97
'0' = 48

Mixed type comparisons

When comparing different numeric types, C++ performs automatic type conversions:

Type promotion in comparisons

#include <iostream>

int main()
{
    int intValue = 42;
    double doubleValue = 42.0;
    float floatValue = 42.0f;
    char charValue = 'A';  // ASCII 65
    
    // Comparisons with type promotion
    std::cout << "Mixed type comparisons:" << std::endl;
    std::cout << "intValue == doubleValue: " << (intValue == doubleValue) << std::endl;  // true
    std::cout << "intValue == floatValue: " << (intValue == floatValue) << std::endl;    // true
    std::cout << "doubleValue == floatValue: " << (doubleValue == floatValue) << std::endl; // true
    
    // Character to integer comparison
    std::cout << "charValue == 65: " << (charValue == 65) << std::endl;  // true
    std::cout << "charValue > 60: " << (charValue > 60) << std::endl;    // true
    
    // Boolean in numeric comparisons
    bool boolValue = true;
    std::cout << "boolValue == 1: " << (boolValue == 1) << std::endl;    // true
    std::cout << "boolValue > 0: " << (boolValue > 0) << std::endl;      // true
    
    // Size type comparisons
    size_t sizeValue = 100;
    std::cout << "sizeValue > intValue: " << (sizeValue > intValue) << std::endl; // true
    
    return 0;
}

Output:

Mixed type comparisons:
intValue == doubleValue: 1
intValue == floatValue: 1
doubleValue == floatValue: 1
charValue == 65: 1
charValue > 60: 1
boolValue == 1: 1
boolValue > 0: 1
sizeValue > intValue: 1

Signed and unsigned comparisons (be careful!)

#include <iostream>

int main()
{
    int signedValue = -1;
    unsigned int unsignedValue = 1;
    
    // ⚠️ Dangerous: signed/unsigned comparison
    std::cout << "Signed/unsigned comparison issues:" << std::endl;
    std::cout << "signedValue = " << signedValue << std::endl;
    std::cout << "unsignedValue = " << unsignedValue << std::endl;
    
    // This might not work as expected!
    std::cout << "signedValue < unsignedValue: " << (signedValue < unsignedValue) << std::endl;
    
    // The signed value gets converted to unsigned, becoming a very large positive number
    std::cout << "signedValue as unsigned: " << static_cast<unsigned int>(signedValue) << std::endl;
    
    // ✅ Safe approach: explicit casting
    std::cout << "\nSafe comparisons:" << std::endl;
    if (signedValue < 0 || static_cast<int>(unsignedValue) > signedValue) {
        std::cout << "Properly handled signed/unsigned comparison" << std::endl;
    }
    
    return 0;
}

Output:

Signed/unsigned comparison issues:
signedValue = -1
unsignedValue = 1
signedValue < unsignedValue: 0
signedValue as unsigned: 4294967295

Safe comparisons:
Properly handled signed/unsigned comparison

The floating-point comparison problem

This is one of the most important concepts in this lesson: never use == or != to compare floating-point numbers directly.

Why floating-point equality fails

#include <iostream>
#include <iomanip>

int main()
{
    // Set precision for better output visibility
    std::cout << std::fixed << std::setprecision(20);
    
    // Simple arithmetic that should equal 1.0
    double result = 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1;
    
    std::cout << "0.1 added 10 times: " << result << std::endl;
    std::cout << "Expected value (1.0): " << 1.0 << std::endl;
    
    // ❌ This comparison fails!
    std::cout << "result == 1.0: " << (result == 1.0) << std::endl;  // false!
    
    // Another example
    double a = 0.1;
    double b = 0.2;
    double sum = a + b;
    
    std::cout << "\na: " << a << std::endl;
    std::cout << "b: " << b << std::endl;
    std::cout << "a + b: " << sum << std::endl;
    std::cout << "Expected (0.3): " << 0.3 << std::endl;
    
    // ❌ This also fails!
    std::cout << "a + b == 0.3: " << (sum == 0.3) << std::endl;  // false!
    
    // Division example
    double division = 1.0 / 3.0;
    double multiplication = division * 3.0;
    
    std::cout << "\n1.0 / 3.0: " << division << std::endl;
    std::cout << "(1.0 / 3.0) * 3.0: " << multiplication << std::endl;
    std::cout << "multiplication == 1.0: " << (multiplication == 1.0) << std::endl;  // false!
    
    return 0;
}

Output:

0.1 added 10 times: 0.99999999999999988898
Expected value (1.0): 1.00000000000000000000
result == 1.0: 0

a: 0.10000000000000000555
b: 0.20000000000000001110
a + b: 0.30000000000000004441
Expected (0.3): 0.29999999999999998890
a + b == 0.3: 0

1.0 / 3.0: 0.33333333333333331483
(1.0 / 3.0) * 3.0: 0.99999999999999988898
multiplication == 1.0: 0

Understanding floating-point representation

#include <iostream>
#include <iomanip>
#include <cmath>

int main()
{
    // Floating-point numbers are approximations
    std::cout << std::fixed << std::setprecision(15);
    
    // Some numbers can be represented exactly
    double exact1 = 0.5;      // 1/2 - can be represented exactly
    double exact2 = 0.25;     // 1/4 - can be represented exactly
    double exact3 = 0.125;    // 1/8 - can be represented exactly
    
    std::cout << "Numbers that can be represented exactly:" << std::endl;
    std::cout << "0.5: " << exact1 << std::endl;
    std::cout << "0.25: " << exact2 << std::endl;
    std::cout << "0.125: " << exact3 << std::endl;
    
    // These comparisons work because values are exact
    std::cout << "0.5 == 0.5: " << (exact1 == 0.5) << std::endl;      // true
    std::cout << "0.25 == 0.25: " << (exact2 == 0.25) << std::endl;   // true
    
    // Numbers that cannot be represented exactly
    double inexact1 = 0.1;    // Cannot be represented exactly in binary
    double inexact2 = 0.7;    // Cannot be represented exactly in binary
    
    std::cout << "\nNumbers that cannot be represented exactly:" << std::endl;
    std::cout << "0.1 stored as: " << inexact1 << std::endl;
    std::cout << "0.7 stored as: " << inexact2 << std::endl;
    
    // Show the difference
    std::cout << "Difference from 0.1: " << (inexact1 - 0.1) << std::endl;
    std::cout << "Difference from 0.7: " << (inexact2 - 0.7) << std::endl;
    
    return 0;
}

Output:

Numbers that can be represented exactly:
0.5: 0.500000000000000
0.25: 0.250000000000000
0.125: 0.125000000000000
0.5 == 0.5: 1
0.25 == 0.25: 1

Numbers that cannot be represented exactly:
0.1 stored as: 0.100000000000000
0.7 stored as: 0.700000000000000
Difference from 0.1: 0.000000000000000
Difference from 0.7: 0.000000000000000

Safe floating-point comparisons

Using epsilon for equality comparisons

#include <iostream>
#include <cmath>
#include <iomanip>

// Function to safely compare floating-point numbers for equality
bool isEqual(double a, double b, double epsilon = 1e-9) {
    return std::abs(a - b) < epsilon;
}

// Function for "close enough" comparisons with relative epsilon
bool isEqualRelative(double a, double b, double relativeEpsilon = 1e-9) {
    // Handle the case where both numbers are very close to zero
    if (std::abs(a) < 1e-12 && std::abs(b) < 1e-12) {
        return true;
    }
    
    // Use relative epsilon based on the larger of the two numbers
    double maxValue = std::max(std::abs(a), std::abs(b));
    return std::abs(a - b) < (relativeEpsilon * maxValue);
}

int main()
{
    std::cout << std::fixed << std::setprecision(15);
    
    // Example of problematic floating-point arithmetic
    double a = 0.1 + 0.1 + 0.1;
    double b = 0.3;
    
    std::cout << "a (0.1 + 0.1 + 0.1): " << a << std::endl;
    std::cout << "b (0.3): " << b << std::endl;
    std::cout << "Difference: " << (a - b) << std::endl;
    
    // ❌ Direct comparison fails
    std::cout << "\nDirect comparison:" << std::endl;
    std::cout << "a == b: " << (a == b) << std::endl;  // false
    
    // ✅ Epsilon comparison succeeds
    std::cout << "\nEpsilon comparison:" << std::endl;
    std::cout << "isEqual(a, b): " << isEqual(a, b) << std::endl;  // true
    
    // More examples
    double x = 1.0 / 3.0;
    double y = x * 3.0;
    
    std::cout << "\nx (1.0 / 3.0): " << x << std::endl;
    std::cout << "y (x * 3.0): " << y << std::endl;
    std::cout << "Direct y == 1.0: " << (y == 1.0) << std::endl;       // false
    std::cout << "isEqual(y, 1.0): " << isEqual(y, 1.0) << std::endl;  // true
    
    // Relative epsilon comparison for larger numbers
    double large1 = 1000000.1;
    double large2 = 1000000.2;
    double largeSum = large1 + large2;
    double expected = 2000000.3;
    
    std::cout << "\nLarge number comparison:" << std::endl;
    std::cout << "largeSum: " << largeSum << std::endl;
    std::cout << "expected: " << expected << std::endl;
    std::cout << "isEqual(largeSum, expected): " << isEqual(largeSum, expected) << std::endl;
    std::cout << "isEqualRelative(largeSum, expected): " << isEqualRelative(largeSum, expected) << std::endl;
    
    return 0;
}

Output:

a (0.1 + 0.1 + 0.1): 0.300000000000000
b (0.3): 0.300000000000000
Difference: 0.000000000000000

Direct comparison:
a == b: 0

Epsilon comparison:
isEqual(a, b): 1

x (1.0 / 3.0): 0.333333333333333
y (x * 3.0): 1.000000000000000
Direct y == 1.0: 0
isEqual(y, 1.0): 1

Large number comparison:
largeSum: 2000000.300000000
expected: 2000000.300000000
isEqualRelative(largeSum, expected): 1
isEqualRelative(largeSum, expected): 1

Safe inequality comparisons

#include <iostream>
#include <cmath>

// Safe "not equal" comparison
bool isNotEqual(double a, double b, double epsilon = 1e-9) {
    return std::abs(a - b) >= epsilon;
}

// Safe "less than" comparison
bool isLess(double a, double b, double epsilon = 1e-9) {
    return (b - a) > epsilon;
}

// Safe "greater than" comparison  
bool isGreater(double a, double b, double epsilon = 1e-9) {
    return (a - b) > epsilon;
}

// Safe "less than or equal" comparison
bool isLessOrEqual(double a, double b, double epsilon = 1e-9) {
    return (a < b) || (std::abs(a - b) < epsilon);
}

// Safe "greater than or equal" comparison
bool isGreaterOrEqual(double a, double b, double epsilon = 1e-9) {
    return (a > b) || (std::abs(a - b) < epsilon);
}

int main()
{
    double a = 1.0;
    double b = 1.0 + 1e-10;  // Very slightly larger than 1.0
    double c = 1.0 - 1e-10;  // Very slightly smaller than 1.0
    
    std::cout << "Testing safe floating-point comparisons:" << std::endl;
    std::cout << "a = " << a << std::endl;
    std::cout << "b = " << b << " (slightly larger)" << std::endl;
    std::cout << "c = " << c << " (slightly smaller)" << std::endl;
    
    std::cout << "\nEquality tests:" << std::endl;
    std::cout << "a == b (direct): " << (a == b) << std::endl;
    std::cout << "isEqual(a, b): " << (std::abs(a - b) < 1e-9) << std::endl;
    
    std::cout << "\nInequality tests:" << std::endl;
    std::cout << "isLess(c, a): " << isLess(c, a) << std::endl;        // true
    std::cout << "isGreater(b, a): " << isGreater(b, a) << std::endl;  // false (too small diff)
    std::cout << "isLessOrEqual(c, a): " << isLessOrEqual(c, a) << std::endl; // true
    
    // More significant differences
    double d = 1.1;
    double e = 1.2;
    
    std::cout << "\nSignificant differences:" << std::endl;
    std::cout << "isLess(d, e): " << isLess(d, e) << std::endl;        // true
    std::cout << "isGreater(e, d): " << isGreater(e, d) << std::endl;  // true
    
    return 0;
}

Output:

Testing safe floating-point comparisons:
a = 1
b = 1 (slightly larger)
c = 1 (slightly smaller)

Equality tests:
a == b (direct): 0
isEqual(a, b): 1

Inequality tests:
isLess(c, a): 0
isGreater(b, a): 0
isLessOrEqual(c, a): 1

Significant differences:
isLess(d, e): 1
isGreater(e, d): 1

Practical applications

Range checking with floating-point numbers

#include <iostream>
#include <cmath>

bool isInRange(double value, double min, double max, double epsilon = 1e-9) {
    return (value > min - epsilon) && (value < max + epsilon);
}

int main()
{
    double temperature = 98.6;
    double normalMin = 98.0;
    double normalMax = 99.0;
    
    std::cout << "Temperature range checking:" << std::endl;
    std::cout << "Temperature: " << temperature << "°F" << std::endl;
    std::cout << "Normal range: " << normalMin << "°F - " << normalMax << "°F" << std::endl;
    
    // Safe range checking
    if (isInRange(temperature, normalMin, normalMax)) {
        std::cout << "Temperature is in normal range" << std::endl;
    } else {
        std::cout << "Temperature is outside normal range" << std::endl;
    }
    
    // Financial calculations example
    double balance = 1000.0;
    double withdrawal = 500.0;
    double deposit = 250.0;
    
    double expectedBalance = balance - withdrawal + deposit;  // Should be 750.0
    double actualBalance = 750.00000001;  // Slight rounding error
    
    std::cout << "\nFinancial calculation:" << std::endl;
    std::cout << "Expected balance: $" << expectedBalance << std::endl;
    std::cout << "Actual balance: $" << actualBalance << std::endl;
    
    // Safe comparison for financial data
    if (std::abs(expectedBalance - actualBalance) < 0.01) {  // Penny precision
        std::cout << "Balances match within acceptable tolerance" << std::endl;
    } else {
        std::cout << "Balance discrepancy detected!" << std::endl;
    }
    
    return 0;
}

Output:

Temperature range checking:
Temperature: 98.6°F
Normal range: 98°F - 99°F
Temperature is in normal range

Financial calculation:
Expected balance: $750
Actual balance: $750
Balances match within acceptable tolerance

Sorting and searching with floating-point data

#include <iostream>
#include <vector>
#include <algorithm>
#include <cmath>

// Custom comparison function for floating-point sorting
bool floatLess(double a, double b, double epsilon = 1e-9) {
    return (b - a) > epsilon;  // a is significantly less than b
}

int main()
{
    std::vector<double> values = {3.1, 2.9, 3.0, 2.99999999, 3.00000001};
    
    std::cout << "Original values:" << std::endl;
    for (double value : values) {
        std::cout << value << " ";
    }
    std::cout << std::endl;
    
    // Sort using custom floating-point comparison
    std::sort(values.begin(), values.end(), [](double a, double b) {
        return floatLess(a, b);
    });
    
    std::cout << "Sorted values:" << std::endl;
    for (double value : values) {
        std::cout << value << " ";
    }
    std::cout << std::endl;
    
    // Search for a value with tolerance
    double searchValue = 3.0;
    auto findWithTolerance = [&](double target) {
        for (size_t i = 0; i < values.size(); ++i) {
            if (std::abs(values[i] - target) < 1e-9) {
                return i;
            }
        }
        return values.size();  // Not found
    };
    
    size_t index = findWithTolerance(searchValue);
    if (index < values.size()) {
        std::cout << "Found " << searchValue << " at index " << index << std::endl;
    } else {
        std::cout << searchValue << " not found" << std::endl;
    }
    
    return 0;
}

Output:

Original values:
3.1 2.9 3 3 3 

Sorted values:
2.9 3 3 3 3.1 

Found 3 at index 1

Best practices for comparisons

Choosing the right epsilon value

#include <iostream>
#include <cmath>
#include <limits>

int main()
{
    // Different epsilon values for different use cases
    const double STRICT_EPSILON = 1e-15;      // Very strict comparison
    const double NORMAL_EPSILON = 1e-9;       // General purpose
    const double LOOSE_EPSILON = 1e-6;        // When precision isn't critical
    const double FINANCIAL_EPSILON = 0.01;    // Financial calculations (penny precision)
    
    double a = 1.0;
    double b = 1.0 + 1e-10;  // Very small difference
    
    std::cout << "Different epsilon tolerances:" << std::endl;
    std::cout << "a = " << a << std::endl;
    std::cout << "b = " << b << std::endl;
    std::cout << "Difference: " << std::abs(a - b) << std::endl;
    
    std::cout << "\nComparison results:" << std::endl;
    std::cout << "Strict (1e-15): " << (std::abs(a - b) < STRICT_EPSILON) << std::endl;
    std::cout << "Normal (1e-9): " << (std::abs(a - b) < NORMAL_EPSILON) << std::endl;
    std::cout << "Loose (1e-6): " << (std::abs(a - b) < LOOSE_EPSILON) << std::endl;
    std::cout << "Financial (0.01): " << (std::abs(a - b) < FINANCIAL_EPSILON) << std::endl;
    
    // Machine epsilon - the smallest difference detectable
    std::cout << "\nMachine epsilon: " << std::numeric_limits<double>::epsilon() << std::endl;
    
    return 0;
}

Output:

Different epsilon tolerances:
a = 1
b = 1
Difference: 1e-10

Comparison results:
Strict (1e-15): 0
Normal (1e-9): 1
Loose (1e-6): 1
Financial (0.01): 1

Machine epsilon: 2.22045e-16

Integer comparisons are always safe

#include <iostream>

int main()
{
    // Integer comparisons are exact and safe
    int a = 42;
    int b = 42;
    int c = 43;
    
    std::cout << "Integer comparisons (always safe):" << std::endl;
    std::cout << "a == b: " << (a == b) << std::endl;  // true
    std::cout << "a != c: " << (a != c) << std::endl;  // true
    std::cout << "a < c: " << (a < c) << std::endl;    // true
    
    // Character comparisons are also exact
    char ch1 = 'A';
    char ch2 = 'A';
    
    std::cout << "\nCharacter comparisons (also safe):" << std::endl;
    std::cout << "ch1 == ch2: " << (ch1 == ch2) << std::endl;  // true
    
    // Boolean comparisons
    bool flag1 = true;
    bool flag2 = false;
    
    std::cout << "\nBoolean comparisons:" << std::endl;
    std::cout << "flag1 != flag2: " << (flag1 != flag2) << std::endl;  // true
    
    return 0;
}

Output:

Integer comparisons (always safe):
a == b: 1
a != c: 1
a < c: 1

Character comparisons (also safe):
ch1 == ch2: 1

Boolean comparisons:
flag1 != flag2: 1

Common mistakes and solutions

Assignment vs. comparison

#include <iostream>

int main()
{
    int x = 5;
    
    // ❌ Common mistake: assignment instead of comparison
    // if (x = 10) {  // This assigns 10 to x, then checks if 10 is true (it is)
    //     std::cout << "This will always execute!" << std::endl;
    // }
    
    // ✅ Correct: comparison operator
    if (x == 5) {
        std::cout << "x equals 5" << std::endl;
    }
    
    // ✅ To avoid the mistake, some people put constants first (Yoda conditions)
    if (5 == x) {  // If you accidentally write 5 = x, it won't compile
        std::cout << "x equals 5 (Yoda style)" << std::endl;
    }
    
    // ❌ Another common mistake with floating-point
    double value = 0.1 + 0.2;
    // if (value == 0.3) {  // This will likely be false!
    //     std::cout << "This might not print" << std::endl;  
    // }
    
    // ✅ Correct floating-point comparison
    if (std::abs(value - 0.3) < 1e-9) {
        std::cout << "Floating-point values are equal within tolerance" << std::endl;
    }
    
    return 0;
}

Output:

x equals 5
x equals 5 (Yoda style)
Floating-point values are equal within tolerance

Summary

Relational operators are essential for comparisons and decision making in C++:

The six relational operators:

  • == and != for equality/inequality
  • <, >, <=, >= for ordering

Key concepts:

  • Integer comparisons are exact and always safe
  • Floating-point comparisons require special care due to precision limitations
  • Type promotion occurs automatically in mixed-type comparisons
  • Signed/unsigned comparisons can be dangerous

Critical floating-point rules:

  • Never use == or != with floating-point numbers directly
  • Use epsilon tolerance for equality comparisons: abs(a - b) < epsilon
  • Choose appropriate epsilon values based on your precision needs
  • Consider relative epsilon for very large or very small numbers

Best practices:

  • Use appropriate epsilon values for floating-point comparisons
  • Be careful with signed/unsigned comparisons
  • Use parentheses for clarity in complex comparisons
  • Test your floating-point logic with edge cases
  • Consider using integer arithmetic when exact precision is required

Understanding these concepts prevents subtle bugs and ensures your comparisons work reliably across different scenarios and data types.

Quiz

  1. What does (5 == 5) evaluate to? a) 5 b) true (1) c) false (0) d) Compiler error

  2. Why should you never use == with floating-point numbers? a) It's illegal syntax b) Floating-point representation is imprecise c) It's too slow d) It only works with integers

  3. What is a safe way to compare if two doubles a and b are equal? a) a == b b) abs(a - b) < epsilon c) a - b == 0 d) a != b

  4. What happens when comparing signed and unsigned integers? a) Compiler error b) Automatic conversion that can be dangerous c) Always works correctly d) Returns random values

  5. Which comparison is always safe and exact? a) double comparison b) float comparison c) int comparison d) string comparison

Practice exercises

Try these exercises to master relational operators:

  1. Floating-Point Comparator: Write functions to safely compare floating-point numbers with different epsilon tolerances.

  2. Grade Calculator: Create a program that assigns letter grades using relational operators, handling floating-point scores correctly.

  3. Range Validator: Build a system that checks if values fall within specified ranges, handling both integer and floating-point data.

  4. Sorting Algorithm: Implement a sorting function that works correctly with floating-point numbers using safe comparison techniques.

Continue Learning

Explore other available lessons while this one is being prepared.

View Course

Explore More Courses

Discover other available courses while this lesson is being prepared.

Browse Courses

Lesson Discussion

Share your thoughts and questions

💬

No comments yet. Be the first to share your thoughts!

Sign in to join the discussion