Start learning free

LESSON 145 OF 414 · LOOPS & GLOBAL VARIABLES

Buggy Code: Sum of Numbers in Rust

Practice Read the full explanation

Inside the code editor we've tried to write a function that takes a number n as argument and returns the sum of all numbers from 0 up to, but not including, n (0 + 1 + 2 + ... + n - 1).

So when we called computeSum(4), we expected our code to print:

6

because 0 + 1 + 2 + 3 = 6. But it seems like we made some mistakes because when we run our code, it prints:

16

Assignment:

Your task is to fix our function such that it correctly computes and returns the desired sum.

STEP 1 OF 1
    Ctrl + Enter to check

    RUST · LOOPS & GLOBAL VARIABLES

    Buggy Code Numbers Sum in Rust, explained

    Problem overview

    The function computeSum should return the sum of the numbers from 0 up to n - 1. For computeSum(4) the expected result is 0 + 1 + 2 + 3 = 6, and the program should print 6. The code as given prints 16 instead.

    The task is to find the mistake and fix it. Neither the loop nor the return statement is wrong in shape. The error is in one name.

    Finding the bug

    The buggy version of the function looks like this:

    fn computeSum(n: i32) -> i32 {
        let mut sum = 0;
        for i in 0..n {
            sum += n;
        }
        return sum;
    }
    

    The wrong output, 16, is a clue. It equals 4 + 4 + 4 + 4, which is n added four times. The loop runs four times, with i equal to 0, 1, 2 and 3, but the body never uses i. It adds the function argument n, which is 4 on every pass.

    Following the loop by hand shows it:

    1. Before the loop, sum is 0.
    2. With i = 0, sum += 4 makes it 4.
    3. With i = 1, it becomes 8.
    4. With i = 2, it becomes 12.
    5. With i = 3, it becomes 16.

    In general, this code adds n to the total n times, so it returns n * n whatever the loop variable does.

    A second clue comes from the compiler. Because i is never used, rustc warns that the variable is unused and suggests the name _i. A warning like this does not stop the program from compiling, but it often points straight at a bug of this kind: the loop variable was declared and then ignored.

    The fix

    The running total must grow by the value that changes from pass to pass, which is i. Changing sum += n; to sum += i; adds 0, then 1, then 2, then 3:

    1. i = 0 leaves sum at 0.
    2. i = 1 makes it 1.
    3. i = 2 makes it 3.
    4. i = 3 makes it 6.

    The loop range stays 0..n. Since a Rust range excludes its end, i stops at n - 1, which is exactly what the task describes.

    The solution in Rust

    fn computeSum(n: i32) -> i32 {
        let mut sum = 0;
        for i in 0..n {
            sum += i;
        }
        return sum;
    }
    fn mainFunction() {
        println!("{}", computeSum(4));
    }
    

    The Rust details worth noting:

    • The range 0..n. It starts at 0 and stops before n. With 0..=n the sum would include n as well, and computeSum(4) would be 10.
    • Compound assignment. sum += i; means sum = sum + i;. The variable needs mut because it changes.
    • The return type. The signature says -> i32, and the function ends with return sum;. Writing just sum without a semicolon would do the same.
    • Names. Rust style prefers compute_sum in snake case. The lesson uses computeSum, which compiles with a style warning. Keep the lesson's names so that the lesson's tests find them.

    Edge cases and common mistakes

    • n = 0 or n = 1. For 0 the range is empty and the function returns 0. For 1 the only value is 0, so the result is 0 as well.
    • Negative n. A range such as 0..-3 is empty, so the function returns 0.
    • Other inputs. computeSum(5) returns 10, and computeSum(3) returns 3.
    • Changing the wrong thing. Switching the range to 1..n does not fix the bug, because the body still adds n. Switching to 1..=n with sum += i would add the wrong numbers for this task.
    • Ignoring warnings. An unused variable is a hint. When the loop variable never appears in the loop body, the loop is probably repeating the same work.
    Keep going with RustAbout 340 step-by-step lessons, from your first line of code to coding interviews. Free to start.
    Start learning free