# 1.5. Conditionals¶

A conditional statement allows a block of code to be executed only when a given logical condition is satisfied. Before introducing the so-called if statement, we need to learn how to express these conditions.

## 1.5.1. Boolean expressions¶

A boolean expression is an expression that is either true or false. For example, the operator == compares two operands and returns true if they are equal and false otherwise:

123 == 123

true

123 == 100 + 23

true

123 == -123

false


true and false are special values that belong to the type Bool:

typeof(true)

Bool

typeof(false)

Bool

typeof(45 == 45)

Bool


Other comparison or relational operators are listed below

Operator

Name

==

equality

!=, ≠

inequality (type \ne + TAB)

<

less than

<=, ≤

less than or equal to (type \le + TAB)

>

greater than

>=, ≥

greater than or equal to (type \ge + TAB)

and here are some more simple examples:

23 ≤ -5

false

4 ≠ 44

true


Note that comparison between floating point numbers and integers work as you would expect:

1.0 == 1

true

1.000000000001 == 1

false


Finally a warning about notation: A common mistake is to use single = for comparison (since it mimics the mathematical notation), but this is incorrect. Single = is an assignment operator, double == is a comparison operator.

## 1.5.2. Logical operators¶

More complex boolean expressions can be formulated using the following logical operators:

&& (and), || (or), and ! (not).


Note that && has higher precedence than || does.

Examples:

3 < 4 && -15 > -10

false

3 < 4 || -15 > -10

true

!(-4 ≥ 4) && (1 > 2 || 1 < 2)

true


### 1.5.2.1. Chained comparisons¶

In Julia, comparisons can be arbitrarily chained:

1 < 2 <= 2 < 3 == 3 > 2 >= 1 == 1 < 3 != 5

true


This syntax is convenient to, for example, determine if a variable is in a given range:

x = -2.3
-3 ≤ x ≤ 4

true


### 1.5.2.2. The if-statement¶

We are now ready to define the if statement for conditional execusion. It has the following syntax:

    if x < y
println("x is less than y")
elseif x > y
println("x is greater than y")
else
println("x is equal to y")
end

• First x < y is evaluated, if true then the corresponding block is evaluated

• Otherwise, x > y is evaluated, if true then the corresponding block is evaluated

• If neither expression is true, the else block is evaluated

• The elseif and else blocks are optional, and elseif can be repeated

# Examples of if-else statements

function check_x(x)
if 0 ≤ x ≤ 10
println("x is between 0 and 10")
elseif !(x < 0)
println("x is not between 0 and 10, and x is not negative (meaning x > 10)")
else
println("x is not between 0 and 10, and x is not not negative (meaning x is negative)")
end
end

check_x (generic function with 1 method)

check_x(π)

x is between 0 and 10

check_x(10.000001)

x is not between 0 and 10, and x is not negative (meaning x > 10)

check_x(2^63)        # trick question - causes Int64 overflow

x is not between 0 and 10, and x is not not negative (meaning x is negative)


### 1.5.2.3. Short-circuit evaluation¶

In a series of boolean expressions connected by these operators, only the minimum number of expressions are evaluated as are necessary to determine the final boolean value of the entire chain. For example:

• In the expression a && b, the subexpression b is only evaluated if a evaluates to true

• In the expression a || b, the subexpression b is only evaluated if a evaluates to false

This allows for convenient error handling, for example the following code will never take the square root of a negative number (which would cause an error):

x = -3
if x ≥ 0 && sqrt(x) < 10
# do something
else
println("Sorry, need a non-negative number with square root strictly less than 10")
end

Sorry, need a non-negative number with square root strictly less than 10


## 1.5.3. Example: Fibonacci, handling special cases¶

One common use for if-statements is the handling of special cases. For example, the Fibonacci sequence is defined by $$F_0 = 0$$, $$F_1 = 1$$, and the recurrence relation

$F_{k} = F_{k-1} + F_{k-2}\qquad \text{for }k\ge 2.$

In the implementation below, the special cases $$F_0$$ and $$F_1$$ are handled separately, and for all other numbers the recurrence relation is used.

function fibonacci(n)
# First special cases
if n == 0
return 0
elseif n == 1
return 1
else
# General case n ≥ 2 - initialize and iterate
Fkold = 0
Fk = 1
for k = 2:n
Fknew = Fk + Fkold
# Swap previous values
Fkold = Fk
Fk = Fknew
end
return Fk
end
end

fibonacci (generic function with 1 method)

fibonacci(10)

55

fibonacci(1000)   # Again be careful with overflow of Int64, but this one is OK

817770325994397771


## 1.5.4. Example: Multiples of 3 and 5¶

Project Euler, Problem 1:

If we list all the natural numbers below 10 that are multiples of 3 or 5, we get 3, 5, 6 and 9. The sum of these multiples is 23.

Find the sum of all the multiples of 3 or 5 below 1000.

Let us create a general function that solves the problem for numbers below a given value n. Note that we can use the remainder operator % to check if a number is a multiple of another number.

function PE1(n)
s = 0
for i = 1:n-1
if i % 3 == 0 || i % 5 == 0
s += i
end
end
s
end

PE1 (generic function with 1 method)


We can now confirm that our function gives the right answer for the example provided:

PE1(10)

23


and we can answer the main question:

PE1(1000)

233168