n = 13
digits = ''
while n > 0:
digits = str(n % 2) + digits
n = n // 2
print(digits)
print(bin(13))
print(int(digits, 2))1101
0b1101
13
Before this lesson
P01.3.1 Choosing a path: if, elif and else P01.2.3 Arithmetic and expressions P01.1.4 Bits, bytes and memory
After this lesson you can
In review. The maths and code on this page are checked by automated tests on every change, but an independent reader has not signed it off yet. Spot a mistake or a confusing step? Tell us.
In P01.1.4 you found that 13 is 1101 in binary. One way to get there is to halve 13, keep the remainder, and go on halving until nothing is left. Thirteen needs four halvings; 100 needs seven; a million needs twenty. How does a program repeat a step when nobody knows in advance how many times it will be needed?
From the last lesson
1. With the tests score >= 70 and then score >= 50, what band does a score of 70 get, and why?
Distinction. \({70 \ge 70}\) is True, and the first True test wins.
2. Which of 0, '0', '' and None count as false in a condition?
0, '' and None. The string '0' has one character in it, so it counts as true.
An if tests once and runs its block at most once. A while loop tests, runs its block if the test is True, and then goes back and tests again. It repeats for as long as the test stays True, and the first time the test is False, control leaves the loop and carries on with the line after it. One run of the block is called a pass, and the block is the loop’s body.
A while loop as a flow chart: the arrow that goes back is what makes it a loop. The test is made before every pass, and once more at the end, when it is False.
The picture is the flow chart of an if with one extra arrow, the one that goes back up. Everything about loops follows from it: the body can run many times, or once, or not at all, and the loop ends only when something in the body has made the test False.
Step 1. One halving by hand. P01.2.3 gave two operators for division in whole numbers: \({13 \mathbin{//} 2}\) is 6, the whole number of halves, and \({13 \mathbin{\%} 2}\) is 1, the remainder. So 13 is 6 twos and 1 left over.
Step 2. Repeat until nothing is left. Halve 6: 3, remainder 0. Halve 3: 1, remainder 1. Halve 1: 0, remainder 1. Now the number is 0 and there is nothing more to halve, so we stop. That was four halvings, and the remainders, in the order they appeared, were 1, 0, 1, 1.
Step 3. Read the remainders upwards. Written from the last one to the first, the remainders are 1101, the binary form of 13: \({8 + 4 + 0 + 1 = 13}\). The first remainder is the 1s digit and the last one is the 8s digit.
Halving 13 down to 0. Each remainder is one binary digit; read upwards, they spell 1101.
Step 4. Say it in Python. Each halving does the same two things: put the new remainder in front of the digits found so far, and halve the number. That is the body. We go on while the number is greater than 0. That is the test.
str turns the remainder into text, and + joins two pieces of text (P01.2.1), so the newest digit lands at the front.
Counting passes. Each pass is preceded by a test that came out True, and the loop ends with one test that came out False. So if the body runs \(k\) times, the test is made \({k + 1}\) times. For 13 the body runs 4 times and the test is made 5 times. A body can also run 0 times: start with n = 0 and the very first test is False.
The three parts of a loop. A loop that is meant to end needs three things:
n = 13);n > 0);n = n // 2).Why the halving loop ends. The body runs only when \({n > 0}\). For such a whole number, \({n \mathbin{//} 2}\) is at most half of \(n\), and half of a positive number is smaller than the number. So every pass makes \(n\) smaller, and it stays a whole number that is at least 0. A whole number cannot keep getting smaller for ever without going below 0, so after some pass \(n\) is 0 and the test is False.
Why the remainders are the binary digits. P01.2.3 tied the two operators together by \(a = {(a \mathbin{//} b) \times b} + {a \mathbin{\%} b}\). With \({b = 2}\), the four halvings of 13 read
\[ \begin{aligned} 13 &= 2 \times 6 + 1 \\ 6 &= 2 \times 3 + 0 \\ 3 &= 2 \times 1 + 1 \\ 1 &= 2 \times 0 + 1 . \end{aligned} \]
Put each line into the one above it, one at a time:
\[ \begin{aligned} 13 &= 2 \times 6 + 1 \\ &= 2 \times (2 \times 3 + 0) + 1 \\ &= 4 \times 3 + 2 \times 0 + 1 \\ &= 4 \times (2 \times 1 + 1) + 2 \times 0 + 1 \\ &= 8 \times 1 + 4 \times 1 + 2 \times 0 + 1 \times 1 . \end{aligned} \]
In the last line, the 1 in \({8 \times 1}\) is the quotient of the third halving, and the fourth line says it is \({2 \times 0 + 1}\): it is the fourth remainder, with 0 left to halve. So the last line is the place-value form of 1101: one 8, one 4, no 2 and one 1. The first remainder is the 1s digit and each later remainder belongs one place further left, which is why the loop puts each new digit in front.
The same equation, \(n = {2 \times (n \mathbin{//} 2)} + {n \mathbin{\%} 2}\), says that the binary digits of \(n\) are those of \({n \mathbin{//} 2}\) with one more digit, the remainder, written after them. So each halving drops the last binary digit, and the loop makes exactly one pass for each binary digit of the number it starts with: 4 for 13, and 7 for 100, which is 1100100.
Trace the halving loop for 13, one row per pass. Before the loop, line 1 binds n to 13 and line 2 binds digits to the empty string. Then:
digits becomes '1'; \({13 \mathbin{//} 2 = 6}\), so n becomes 6.digits becomes '01'; n becomes 3.digits becomes '101'; n becomes 1.digits becomes '1101'; n becomes 0.1101.The trace table of the halving loop. Each row shows the test, the remainder and the names after the pass; the yellow False is the test that ends the loop.
Counted line by line, the program ran 16 lines: lines 1 and 2 once, the test on line 3 five times, lines 4 and 5 four times each, and line 6 once. The body ran 4 times and the test 5 times, as the counting rule says.
The loop from the build-up, then two checks: bin gives Python’s own binary form of a number, and int with a second argument of 2 reads binary text back into a number (both met in P01.1.4).
1101
0b1101
13
The 0b at the front of bin’s answer only marks the text as binary. Now count the passes with a second name that the body increases by one, for a bigger number:
1100100 7
Seven passes for 100, one for each of its seven binary digits. This repeat-until-done shape is the skeleton of every training loop: a model’s parameters get one small update per pass, and the loop stops when the loss has stopped falling or a budget of passes is used up (ML01.5).
This module’s interactive, the flow-chart tracer, lives in lesson P01.3.3. Its second program is this lesson’s halving loop. Set n with the slider and step through: the test lights up before every pass, and a counter shows how many times the body has run. Try 64, then 63, then 0.
Wrong beside right. Counting down by 2 from 13 never lands on 0, so a test of n != 0 never becomes False. A test of n > 0 stops after 7 passes, at \(-1\).
“The loop will stop by itself.”
Only if the body changes what the test reads. Leave out the update and the halving loop never ends:
n stays 13, so \({13 > 0}\) is True for ever. A program stuck like this is stopped from the keyboard by pressing Ctrl+C, and Python reports a KeyboardInterrupt. When a loop does not end, look first for its start, its test and its update.
“Testing != is as good as testing >.”
Only if the update is sure to land exactly on the stop value. Counting down by 2 from 13 visits only odd numbers, so it jumps from 1 to \(-1\) and never equals 0. A test such as n > 0 stops as soon as the value has gone past the line, wherever it lands.
“My loop prints 1 to 5.”
Count the passes. This loop runs its body once for each value of count that passes the test, and 5 does not pass count < 5:
It prints four lines, 1 to 4: a loop that is off by one. Test count <= 5 instead, or start at 0 and print count + 1. Before you trust a loop, check its first pass and its last.
“A loop always runs its body at least once.”
A while loop tests first. With n = 0 the halving loop’s first test is False, the body never runs, and digits stays the empty string, so the program prints an empty line, although bin(0) is '0b0'. Exercise 2 repairs it.
1. When does a while loop stop?
When its test is False at the moment it is made, at the top of a pass. The loop then ends and the line after its body runs.
2. Name the start, the test and the update of the halving loop.
Start: n = 13 (and digits = ''). Test: n > 0. Update: n = n // 2.
3. A loop’s body ran 4 times. How many times was its test made?
5 times: once before each of the 4 passes, and once more when it came out False.
4. What does the halving loop print when n starts at 6?
110. The remainders are 0, 1 and 1, and read upwards they give 110, which is \({4 + 2 = 6}\).
5. Why does while n != 0: with the update n = n - 2 never end when n starts at 13?
Subtracting 2 from an odd number gives an odd number, so n goes 13, 11, …, 1, \(-1\), and never equals 0. The test n != 0 is True for ever.
1. ★ Trace the halving loop for n = 6 in a trace table with one row per pass, and check your answer with bin(6).
Start: digits is '', n is 6. Pass 1: \({6 > 0}\) is True, the remainder is 0, digits is '0', n is 3. Pass 2: \({3 > 0}\) is True, the remainder is 1, digits is '10', n is 1. Pass 3: \({1 > 0}\) is True, the remainder is 1, digits is '110', n is 0. The test \({0 > 0}\) is False, so the loop ends after 3 passes and 4 tests. bin(6) is '0b110', which agrees.
2. ★★ What does the halving program print when n starts at 0, and why? Add an if statement after the loop so that it prints 0 in that case and nothing changes for any other number.
3. ★★★ For which starting values does the halving loop make exactly 7 passes? Explain your answer with binary digits.
The loop makes one pass for each binary digit of its starting value, because halving drops the last digit and the loop stops when no digits are left. So the answer is every number with exactly 7 binary digits. The smallest is 1000000, which is \({2^6 = 64}\), and the largest is 1111111, which is \(64 + 32 + 16 + 8 + 4 + 2 + 1 = 127\). Every number from 64 to 127 makes 7 passes; 63 makes 6 and 128 makes 8.
A while loop repeats its body for as long as its test stays True.
The arrow back to the test makes a loop.
n % 2 and n // 2 in a loop give the binary digits, last one first; bin checks them.Sources. Each was opened and checked against this lesson on 12 November 2026.
x % 2 for the last bit and x // 2 in a while loop.0b.Next. P01.3.3 Repeating with for and range meets a loop that does the start, the test and the update for you, by visiting the items of a sequence one at a time.
This lesson unlocks
P01.3.3 Repeating with for and range