Lesson 5.3. Checking intervals

In C, it is not uncommon to have to check if a variable is included in a given interval. For example, between 0 and 100 for a percentage.

Nested if

There are several solutions, we can obviously nest if to obtain a code of the type:

if (p>=0) {
    if (p<=100) {
        // Valid percentage
        // ...
    }
}

Suppose we also want to execute a block of instructions when the percentage is not valid. You will quickly realize that this solution does not allow to insert an else properly.

The mistake to avoid

Beginning developers would be tempted to write the following code:

if ( 0 <= p <= 100 ) {
    // Valid percentage
    // ...
}

This solution compiles but will not have the expected behavior. Indeed, to analyze this code, you have to refer to the operator precedence table. The operator <= has associativity from left to right, so it is like writing :

if ( (0 <= p) <= 100 ) { ... }

The test (0 <= p) can only return 0 or 1. In both cases, it will always be less than 100. The test will always be true, so you might as well delete it, it won't change anything.

The right way

The right solution to test an interval is to use a logical operator to combine the two tests:

if ( p>=0 && p<=100 ) {
    // Valid percentage
    // ...
}

This time, this solution will work. The test will be true if p is greater than 0 and p is less than 100.

The other right solution

There is another solution which is related to the previous one by De Morgan's law. We will demonstrate this. If you are not familiar with Boolean logic, this should not prevent you from you from understanding the final solution.

In the test if ( p>=0 && p<=100 ), we will set the following boolean variables:

Our condition becomes if ( A && B ), which is represented by the logical equation:

$$ A.B $$

By applying De Morgan's law, we can now write :

$$ A.B = \overline { \overline{A} + \overline{B}} $$

If we replace back A and B by p>=0 and p<=100 respectively, we can also write :

$$ \overline{A} = \overline{(p>=0)} = p<0 $$ $$ \overline{B} = \overline{(p<=100)} = p>100 $$

This gives us the following alternative code:

if (!( p<0 || p>100 )) {
    //Valid percentage
    // ...
}
Do not mix the two solutions with a writing like if ( p>=0 || p<=100 ).
All integers are greater than 0 OR less than 100.

This test is always true.

Exercises

Exercise 1

Write a program that asks the user to enter a grade. If the grade is between 0 and 20, the program displays Grade recorded, otherwise it displays Non valid grade.

float grade;

// Ask for the grade
// COMPLETE HERE

// Check if the grade is valid [0;20]
// COMPLETE HERE 

Here is the expected display:

Enter your grade: 23
Non valid grade

Exercise 2

Write a program that displays the notation associated with a note entered by the user by testing each interval.

Interval Message
[0 ; 10[ rejected
[10 ; 12[ Passing
[12 ; 14[ With honors
[14 ; 16[ High honors
[16 ; 20] Highest honors

Here is the expected display:

Enter your grade: 13.8
With honors

Quiz

What does the following code display?

if ( 0<x<10 )
    printf ("Crac");
else 
    printf ("Boum");
Check Bravo! The test is useless because it will always be true. Operators precedence => (0<note)<100. Try again...

How to test if an integer a is between 12 and 52 inclusive?

Check Bravo! It requires that a be greater than or equal to 12 AND less than or equal to 52. Try again...

What does the following code display?

if ( x<0 && x>100 )
    printf ("Crac");
else 
    printf ("Boum");
Check Bravo! So try to find a number smaller than 0 AND greater than 100. Good luck! Try again...

How to test if an integer a isn't in the interval [12 ; 52] (in other words if a is 12, the test is false) ?

Check Bravo! The variable a must be strictly less than 12 OR strictly greater than 52. Try again...

What does the following test do?

if ((x<=7 || x>=12) == 0)
Check Bravo! By applying De Morgan's law, we can show this is equivalent to if (x>7 && x<12). Try again...

See also


Last update : 11/22/2022