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 w=8 w=16 w=32
UMinw 0x00 0x0000 0x00000000
UMaxw 0xFF 0xFFFF 0xFFFFFFFF
TMinw 0x80 0x8000 0x80000000
TMaxw 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 x of w bits, we convert binary to its unsigned encoding with:

B2Uw(x)=2w1xw1+i=0w22ixi

Note we unfold the summation on the RHS by one term to make it's relationship to T2Uw clearer.

Two's-Complement

Represents negative numbers along with nonnegative ones. Given an integral type x of w bits, we convert binary to its twos'-complement encoding with:

B2Tw(x)=2w1xw1+i=0w22ixi

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. T2U and U2T reflect this method of casting:

T2Uw(x)={x+2wx<0xx0U2Tw(x)={xxTMaxwx2wx>TMaxw

Expansion

For unsigned encoding, use zero extension to convert numbers to larger types. For example, 10102 can be expanded to 8-bit 000010102.

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, 10102 can be expanded to 8-bit 111110102.

Truncation

Let x=xw1,,x1,x0 and x=xk1,,x1,x0.

In unsigned encoding, truncating x to k bits is equal to xmod2k. This is because ximod2k=0 for all ik meaning

B2Uk(x)=B2Uw(x)mod2k.

In two's-complement encoding, truncating x to k bits is equal to U2Tk(T2Uw(x)mod2k). Like with unsigned truncation, B2Uk(x)=B2Uw(x)mod2k. Therefore

U2Tk(B2Uk(x))=U2Tk(B2Uw(x)mod2k).

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 w-bit integral types, denoted +wu, behaves like so:

x+wuy={x+y2wif x+y2wx+yotherwise

This is more simply expressed as x+wuy=(x+y)mod2w.

Two's-complement addition, denoted +wt operates similarly:

x+wuy={x+y2wif x+y2w1x+y+2wif x+y<2w1x+yotherwise

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:

In C, it is undefined behavior to shift by more than the width w of an integral type or by a negative value.

Multiplication

Unsigned multiplication, denoted with the wu operator, is defined as follows:

xwuy=(xy)mod2w

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.

Powered by Forestry.md