Understanding the building blocks of digital information.
In our digital world, everything from your phone to your car runs on computers. At their core, computers speak a language of numbers. Understanding concepts like binary, signed integers, and floating-point numbers isn't just for programmers; it gives you a fundamental insight into how technology works. It helps demystify computers and empowers you to understand topics like networking, data storage, and digital color representation.
The most basic unit of information in computing is a bit. A bit can only have one of two values: 0 or 1. Think of it like a light switch that can be either off (0) or on (1).
A byte is an ordered collection of 8 bits. By grouping bits together, we can represent more complex information. With 8 bits, there are 28 (or 256) possible combinations, from 00000000 to 11111111.
A word is a larger group of bits, and its size depends on the computer's architecture. Common word sizes are 16, 32, or 64 bits. A larger word size allows a computer to process more data at once.
When we talk about file sizes or storage capacity, we often use prefixes like kilo, mega, and giga. However, there's a common point of confusion: whether these prefixes refer to powers of 1000 or powers of 1024.
The distinction explains why a "1 TB" hard drive might appear as "0.909 TB" or "931 GB" in your operating system – it's because the OS is using the 1024-based calculation.
Computers use the binary system because it's easy to represent with physical hardware (on/off, high/low voltage). Each position in a binary number represents a power of 2, starting from the right (20, 21, 22, etc.). This example shows an unsigned integer, where all bits contribute to the magnitude.
Click the switches below to turn bits on (1) or off (0) and see how the decimal and hexadecimal values change.
How do computers store negative numbers? The most common method is Two's Complement. In this system, the leftmost bit is the "sign bit". If it's 0, the number is positive and calculated normally. If it's 1, the number is negative. To find the value of a negative number, you invert all the bits (a NOT operation), add one, and then make the result negative.
The leftmost bit determines the sign. An 8-bit signed integer can represent numbers from -128 to 127.
For numbers with fractions (like 3.14159), computers use a format called floating-point. It's similar to scientific notation, splitting the number into a sign, an exponent, and a fractional part (mantissa). This demo uses the 16-bit "half-precision" format (1 sign bit, 5 exponent bits, 10 mantissa bits). The formula is: (-1)Sign x 2(Exponent - 15) x (1 + Mantissa). The '15' is the exponent bias.
We're used to the decimal (base-10) system, which uses ten digits (0-9). Other bases are common in computing:
This tool lets you convert a number from any of the common bases to all the others. Try converting your age to binary or your zip code to hexadecimal!
-
-
-
-
When a number is larger than a single byte (e.g., a 32-bit integer), the computer needs to decide the order in which to store those bytes in memory. This ordering is called endianness.
0x12345678
would be stored in memory as the bytes 12
, 34
, 56
, 78
.0x12345678
would be stored as 78
, 56
, 34
, 12
.This is crucial in networking, file formats, and low-level programming. Most network protocols (like TCP/IP) use big-endian, which is why it's also called "network byte order". Most modern desktop CPUs (like Intel and AMD x86) are little-endian.
Enter a 32-bit hexadecimal number to see how it's stored in memory in both big-endian and little-endian systems.
-
Logical operations work on individual bits. They are fundamental to how computers make decisions and perform calculations. Here you can see how they work by comparing two bytes bit-by-bit.
The NOT operation is unique because it only takes one input and inverts all its bits (0 becomes 1, 1 becomes 0). The result of NOT on Byte A is shown below.
A quick and efficient way to check if a number is even or odd in binary is by using the bitwise AND operator with the number 1. This works because:
When you perform a bitwise AND with 1 (which is 00000001 in an 8-bit representation), all bits except the least significant bit are effectively masked out. The result will be 0 if the number is even, and 1 if the number is odd.
This is equivalent to checking the remainder when dividing by 2 (N % 2), but often faster at a low level of computation.
Bitwise shifts and rotations move the bits of a binary number to the left or right. These operations are crucial for low-level programming, optimizing calculations, and manipulating data at the bit level.
Manipulate an 8-bit number using shift and rotate operations. Click the bits to toggle them, then use the buttons to see the effects.
Binary-Coded Decimal (BCD) is a way to represent decimal numbers where each decimal digit is represented by its own 4-bit binary code (a nibble). For example, the decimal number 123 would be represented as `0001 0010 0011` in BCD.
While it might seem less efficient than pure binary (since 4 bits can represent 0-15, but BCD only uses 0-9), BCD has some advantages:
Is it used anymore? Yes, BCD is still used in specific applications where decimal precision is paramount, such as:
This is a classic bitwise trick to swap the values of two variables without needing a temporary third variable. It leverages the properties of the XOR operation (A XOR A = 0 and A XOR B XOR B = A).
In older Intel x86 assembly languages, a common optimization trick was to use XOR CX, CX
to set the CX
register to zero, instead of using MOV CX, 0
.
XOR CX, CX
is a shorter instruction (fewer bytes) than MOV CX, 0
. Smaller instructions can be fetched and decoded faster.MOV CX, 0
requires the processor to fetch an immediate value (the '0') from memory or instruction stream. XOR CX, CX
operates directly on the register's current value, which is already available in the CPU.
While this optimization was significant in the days of limited cache and simpler pipeline architectures, modern CPUs have highly sophisticated pipelines, out-of-order execution, and predictive capabilities. Compilers are also much smarter. Today, the performance difference between XOR REG, REG
and MOV REG, 0
is often negligible, and sometimes MOV
can even be faster due to specific micro-architectural optimizations (e.g., zeroing idioms). However, it remains a fascinating example of low-level optimization.
Different programming languages provide various ways to represent numbers in different bases and perform bitwise operations. Here's a quick overview for common languages like C, Java, JavaScript, and Python:
123
) are written without any special prefix in all these languages.0b
or 0B
(e.g., 0b1011
). This is supported in Java 7+, C++14+, JavaScript (ES6+), and Python.0x
or 0X
(e.g., 0xFF
).0
(e.g., 0755
).0o
or 0O
(e.g., 0o755
).0
prefix for octal is deprecated in strict mode; explicit octal literals use 0o
or 0O
(ES6+).The core bitwise operations use very similar syntax across C, Java, JavaScript, and Python:
&
(e.g., a & b
)|
(e.g., a | b
)^
(e.g., a ^ b
)~
(e.g., ~a
).
~x
is equivalent to -x - 1
due to Python's handling of arbitrary precision integers.<<
(e.g., a << 2
). This generally multiplies the number by powers of 2.>>
(e.g., a >> 2
). This generally divides the number by powers of 2.
>>>
which always fills with zeros from the left.