Start learning free

LESSON 136 OF 338 · LOOPS & GLOBAL VARIABLES

Sum of Numbers in Go: Fixing the Buggy Loop

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 0 through 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

    GO · LOOPS & GLOBAL VARIABLES

    Buggy Code Numbers Sum in Go, explained

    What the code is supposed to do

    The function computeSum takes an integer n and returns the sum of the whole numbers from 0 up to n - 1. For computeSum(4) that is 0 + 1 + 2 + 3 = 6, and the program should print 6. The code you start with prints 16:

    func computeSum(n int) int {
        sum := 0
        for i := 0; i < n; i++ {
            sum += n
        }
        return sum
    }
    

    What goes wrong

    The loop is set up correctly. Its counter i takes the values 0, 1, 2 and 3, and it stops before reaching n. The mistake is in what the loop adds. The line sum += n adds the parameter n, which is 4 on every pass, instead of the counter i, which changes.

    The hint in the lesson, "16 is 4 + 4 + 4 + 4", describes it exactly. The loop makes four passes and adds 4 each time:

    i = 0: sum = 0 + 4  = 4
    i = 1: sum = 4 + 4  = 8
    i = 2: sum = 8 + 4  = 12
    i = 3: sum = 12 + 4 = 16
    

    In general, the loop runs n times and adds n each time, so the result is always n * n. That is why 4 gives 16, 5 would give 25, and so on. The counter exists but never takes part in the sum.

    Fixing it step by step

    1. Find the line that updates the total. It is the only line in the loop body: sum += n.
    2. Ask which value should go in. The task adds 0, then 1, then 2, up to n - 1. Those are exactly the values the loop counter takes.
    3. Replace n with i. The line becomes sum += i.
    4. Leave everything else. The start value 0, the condition i < n and the return are already right.

    The fixed code in Go

    func computeSum(n int) int {
        sum := 0
        for i := 0; i < n; i++ {
            sum += i
        }
        return sum
    }
    
    func mainFunction() {
        fmt.Println(computeSum(4))
    }
    
    /* Explanation:
    The problem was on line 4 because we added n to sum, and so for computeSum(4) for example:
    0. sum is initially 0. We enter the for loop:
    1. When i is 0 => sum += 4 => sum is now 4
    2. When i is 1 => sum += 4 => sum is now 4 + 4 = 8
    3. When i is 2 => sum += 4 => sum is now 8 + 4 = 12
    4. When i is 3 => sum += 4 => sum is now 12 + 4 = 16
    
    In general, that code would add n to sum for n times, so sum would be n * n when the loop ends.
    On line 4, we should add i to sum instead (sum += i).
    
    And so for computeSum(4) for example:
    0. sum is initially 0. We enter the for loop:
    1. When i is 0 => sum += 0 => sum is now 0
    2. When i is 1 => sum += 1 => sum is now 0 + 1 = 1
    3. When i is 2 => sum += 2 => sum is now 0 + 1 + 2 = 3
    4. When i is 3 => sum += 3 => sum is now 0 + 1 + 2 + 3 = 6
    */
    

    With the fix, the program prints:

    6
    

    Go details worth knowing:

    • The comment block. Text between /* and */ is a comment. The compiler ignores it.
    • The compiler can't catch this bug. Adding n instead of i is valid Go, so the program compiles and runs and only the output is wrong.
    • int arithmetic. Sums stay exact as long as they fit in 64 bits, which is far beyond anything this lesson uses.

    How to find a bug like this

    When the output is wrong, compare it with the expected value and look for a pattern. Here, 16 is 4 * 4, which suggests that the same number is added several times. That points at the line that updates the total, and then at the question of whether the added value changes from pass to pass. A short trace on paper, like the table above, confirms the suspicion in a minute.

    Common mistakes

    • Changing the loop bound instead of the body. Using i <= n would add one more pass. With the fix applied, that gives 0 + 1 + 2 + 3 + 4 = 10, not 6. The task excludes n itself.
    • Starting i at 1. That gives the right answer here, because adding 0 changes nothing, but the loop then starts one pass later than the task describes.
    • Using a formula without testing it. The sum of the numbers from 0 to n - 1 is n * (n - 1) / 2, which gives 6 for 4. A formula is fine, but this lesson fixes the loop.
    • Resetting sum inside the loop. Moving sum := 0 into the loop body would restart the total on every pass, and return sum would not even compile because sum would be out of scope.

    Checking your fix

    Run the code in the editor above. It should print 6. Other values to try: computeSum(1) is 0, computeSum(0) is 0 because the loop never runs, and computeSum(5) is 10.

    Keep going with GoAbout 340 step-by-step lessons, from your first line of code to coding interviews. Free to start.
    Start learning free