Integers
Overview
Integers are typically encoded using either unsigned encoding or two's-complement. The following table highlights how the min and max of these encodings behave:
| Value | |||
|---|---|---|---|
0x00 | 0x0000 | 0x00000000 | |
0xFF | 0xFFFF | 0xFFFFFFFF | |
0x80 | 0x8000 | 0x80000000 | |
0x7F | 0x7FFF | 0x7FFFFFFF |
The width of an integer type refers to the number of bits used in the type's binary representation. It's precision refers to the number of bits used in the type's binary representation, excluding those used for signedness.
Unsigned Encoding
Always represents nonnegative numbers. Given an integral type
Note we unfold the summation on the RHS by one term to make it's relationship to
Two's-Complement
Represents negative numbers along with nonnegative ones. Given an integral type
Casting
Most implementations of C cast an object of signed type to unsigned type and vice versa, most implementations simply re-interpret the object's binary representation. This casting may happen implicitly if comparing or operating on signed and unsigned objects in the same expression.
Expansion
For unsigned encoding, use zero extension to convert numbers to larger types. For example,
For two's-complement, use sign extension to convert numbers to larger types. This means the additional leftmost bits are set to match the sign bit of the original number. For example,
Truncation
Let
In unsigned encoding, truncating
In two's-complement encoding, truncating
Arithmetic
Addition
Addition of two unsigned or two two's-complement numbers operate in much the same way as grade-school arithmetic. Digits are added one-by-one and overflows "carried" to the next summation. Overflows are truncated; the final carry bit is discarded in the underlying bit adder.
Unsigned addition of
This is more simply expressed as
Two's-complement addition, denoted
Unlike with unsigned addition, there is no simpler modulus operation that can be applied.
Shifting
Left shift operations (<<) drop the k most significant bits and fills the right end of the result with k zeros. Right shift operations (>>) are classified in two ways:
- Logical
- Drops the
kleast significant bits and fills the left end of the result withkzeros. - This mode is always used when calling
>>on unsigned data. - Sometimes denoted as
>>>to disambiguate from arithmetic right shifts.
- Drops the
- Arithmetic
- Drops the
kleast significant bits and fills the left end of the result withkcopies of the most significant bit. - This mode is usually used when calling
>>on signed data.
- Drops the
In C, it is undefined behavior to shift by more than the width
Multiplication
Unsigned multiplication, denoted with the
Similarly, two's-complement multiplication is defined as follows: $$x *_w^t y = U2T_w((x \cdot y) \bmod 2^w)$$
Division
Integer division divides the result and discards any fractional result. This has the same effect as rounding toward zero.