Integers (ℤ) are whole numbers that include negatives, zero, and positives. They are widely used in computing to represent quantities, counters, and positions.
What are integers?
Integers are a fundamental number system used extensively in computing and mathematics. An integer is a whole number that can be positive, negative, or zero. Unlike other number types such as decimals or fractions, integers do not have any fractional or decimal parts.
The complete set of integers
The set of integers is represented by the symbol ℤ, derived from the German word Zahlen, meaning “numbers”.
ℤ = { ..., -3, -2, -1, 0, 1, 2, 3, ... }
This set includes:
Positive integers: 1, 2, 3, ...
Negative integers: -1, -2, -3, ...
Zero: 0
Integers are infinite in both the positive and negative directions. Every positive integer has a corresponding negative counterpart (called its additive inverse), and zero is the unique integer that is neither positive nor negative.
Properties of integers
Whole values only – no fractions or decimals
Infinite set – continues indefinitely in both directions
Closed under addition, subtraction, and multiplication – adding, subtracting, or multiplying any two integers always gives another integer
Not closed under division – dividing one integer by another does not always result in an integer
Practice Questions
FAQ
Two’s complement is preferred because it simplifies binary arithmetic and avoids the complications associated with other methods like sign-and-magnitude or one’s complement. In two’s complement, there is only one representation for zero, avoiding the issue of having both positive and negative zero. Arithmetic operations such as addition, subtraction, and multiplication can be carried out without needing special rules for negative values. The binary circuitry used for unsigned arithmetic can also be used directly for signed two’s complement numbers, making it hardware-efficient. Additionally, overflow detection becomes straightforward: it can be checked by examining carry bits. The mathematical rules work seamlessly, meaning subtracting a number is equivalent to adding its two’s complement. This makes two’s complement more consistent and reliable in programming, especially in low-level systems and embedded computing. Its ability to represent a wider range of negative values than positive ones (in fixed-bit formats) also ensures efficient use of available bits.
When an integer exceeds the maximum or minimum value that a specific data type can store, it results in overflow or underflow. In most systems using fixed-bit integer representation (such as 8-bit, 16-bit, or 32-bit), exceeding the maximum positive value causes the number to wrap around into the negative range (overflow), and going below the minimum negative value wraps around into the positive range (underflow). For example, in an 8-bit signed system where the range is -128 to 127, attempting to store 128 will result in -128. This happens due to the way binary arithmetic operates and is especially common in languages like C or C++ that do not perform automatic range checking. In higher-level languages like Python, the integer type automatically expands to accommodate large values, so overflow does not occur. Programmers working with fixed-size integers must implement checks or use larger data types to prevent errors from overflow and underflow.
Negative integers can affect bitwise operations significantly because they are represented in two’s complement form, which alters their binary pattern compared to positive values. Bitwise operations such as AND, OR, XOR, and NOT operate directly on the bits of the number, so the internal binary layout becomes crucial. For instance, applying a bitwise NOT to a negative number yields a result that may seem unintuitive unless you understand its two’s complement representation. Furthermore, shifting negative integers using right shift (>>) can be arithmetic (preserving the sign bit) or logical (shifting in zeros), and this behaviour varies between programming languages. For example, in Java, right-shifting a negative number retains the sign, while in JavaScript, it might not. This makes debugging more difficult if bitwise operations are used blindly. It is important to fully understand how your language of choice represents and manipulates signed integers before applying bitwise logic, especially when dealing with file I/O, graphics, or cryptographic functions.
Zero is considered an integer because it fits the definition of a whole number and belongs to the set ℤ. Mathematically, it is the additive identity, meaning that any integer added to zero remains unchanged (e.g. 5 + 0 = 5). In computing, zero has special importance across various contexts. It is often used to initialise counters and variables, providing a known starting value. It also serves as a logical control in conditions; for example, many programming languages treat zero as false in boolean expressions, and non-zero values as true. Zero is crucial in division checks, as dividing by zero causes runtime errors or exceptions. It also marks the end of strings in languages like C, using the null terminator (\0). In memory management, zero-filled memory often indicates unused or cleared space. Overall, zero plays a pivotal role not only in arithmetic but also in logic, control structures, and memory representation.
In low-level programming languages like C or assembly, integer data types are closely tied to the hardware architecture and have fixed sizes such as int8, int16, int32, and int64. The programmer must explicitly choose the correct type, and failure to do so can result in overflow, truncation, or platform-dependent bugs. These languages often provide both signed and unsigned variants, and arithmetic operations must be carefully managed to avoid unexpected behaviour. By contrast, high-level programming languages like Python abstract away these details. Python’s int type automatically expands to accommodate very large values, using arbitrary-precision arithmetic. While this simplifies development and reduces the chance of overflow, it can result in reduced performance for high-frequency calculations. Other languages like Java or C# offer a middle ground, providing fixed-size integers (e.g. int, long) with some built-in safety checks. The main difference lies in the balance between control and convenience, with low-level languages offering more control and high-level languages favouring ease of use.
