Why do computers count from zero?

Solution 1:

Counting arrays from 0 simplifies the computation of the memory address of each element.

If an array is stored at a given position in memory (it's called the address) the position of each element can be computed as

element(n) = address + n * size_of_the_element

If you consider the first element the first, the computation becomes

element(n) = address + (n-1) * size_of_the_element

Not a huge different but it adds an unnecessary subtraction for each access.

Edit

  • The usage of the array index as an offset is not a requirement but just an habit. The offset of the first element could be hidden by the system and taken into consideration when allocating and referencing element.

  • Dijkstra published a paper "Why numbering should start at zero" (pdf) where he explains why starting with 0 is a better choice. Starting at zero allows a better representation of ranges.

Solution 2:

While the principles below apply to decimal as well any other base, Counting from 0 in computers can be easily understood naturally from the fixed-digit binary system of representing numbers used in computers. If you have 8 bits, then there are 256 possible combinations of 1s and 0s that can be expressed. You could use these 8-bit to express the numbers 1-256, but this would leave out 0 which is useful in mathematics as a number in and of itself, so they are used to express the numbers 0-255.

This already sets a precedent of a natural order starting from 0 (all 0's in the binary representation) to 255 (all 1's in an 8-bit number). Considering the system of representing numbers, starting from 0 makes sense because 0 is the "first" number in the system, so 1 is the "second" number, and so forth.

An additional reason why starting from 0 in computers is so convenient is due to the concept of offsets. An offset is a number representing the distance from a location in memory or hard disk or any other "addressable" medium. In computers, practically all data is stored linearly, meaning that there is an order to the data, a first a byte, a second byte, etc. It is convenient to express location of "areas" of data via an offset. What is the first byte in a block of data? It is at offset '0', which means it is found 0 bytes after the first byte in the block of data. While it is possible to have "1" designate the first byte, this creates complications in the representation of the data for several reasons:

  • By the exclusion of 0 from being used to address data, you reduce the number of things you can address with an 8-bit number by one.
  • To calculate the offset, which is necessary at the hardware level of data access, at some point you have to subtract one from the numbering, which introduces a complexity.
  • Pointers to a block of data always point to the first block, so arithmetic is straightforward when you start from 0. (ie, the 1st byte in the first block of the first cluster of data is 0 + 0 + 0 when you start from 0, it is 1 + 1 + 1 - 1 -1 when you start from 1.) The arithmetic for this when you start from 1 with nested datastructures like this example can be confusing.