Programming

# (Integer, Floats, Complex Numbers)

When you learn a new language, the first thing you usually do is scream
Hello World! Because we all need to be noticed. The second thing we do is
check if the math makes sense, playing around with numbers and arithmetic
operations. Numbers can be integers, float, or complex. Because humans
have 10 fingers, we have learned to represent numbers as decimals. Computers, however, are much more Hamletian. Binary believers have a point:
why waste all these bytes if we can just state that either things are (True)
or they are not (False)? In addition, since computers care about equality
for extraterrestrial beings, they also let you represent things in other basis

## Integers

Python represents integers (positive and negative whole numbers) using the
int (immutable) type. For immutable objects, there is no difference between
a variable and an object reference.
The size of Python’s integers is limited only by the machine memory, not
by a fixed number of bytes (the range depends on the C or Java compiler
that Python was built with). Usually plain integers are at least 32-bit long (4
bytes)1
.To see how many bytes an integer needs to be represented, starting
in Python 3.1, the int.bit length() method is available:

To have an idea of how much this means: 1K of disk memory has 1024 × 8 bits = 210
bytes

The optional base argument must be an integer between 2 and 36 (inclusive). If the string cannot be represented as the integer in the chosen base,
this method raises a ValueError exception. For example, this will happen
if we try to obtain a binary representation with s=‘12’.

## Floats

Numbers with a fractional part are represented by the (immutable) type
float. When we use single precision, a 32-bit float is represented by: 1 bit
for sign (negative being 1, positive being 0) + 23 bits for the significant
digits (or mantissa) + 8 bits for the exponent. On a typical computer
system, a double-precision (64-bit) binary floating-point number has a
coefficient of 53 bits, an exponent of 11 bits, and one sign bit. Also, the
exponent is usually represented using the biased notation, where you add the
number 127 to the original value2.

### Comparing Floats

We should never compare floats for equality nor subtract them. The reason
for this is that floats are represented in binary fractions. There are several
2Biasing is done because exponents have to be signed values to be able to represent
tiny and huge values, but the usual representation makes comparison harder. To solve this
problem, the exponent is adjusted to be within an unsigned range suitable for comparison.

numbers that are exact in a decimal base but not exact in a binary base (for
example, the decimal 0.1). Equality tests should instead be done in terms of
some predefined precision. For example, we could employ the same approach
as the Python’s unittest module: assert AlmostEqual:

Float numbers can also be compared by their bit patterns in memory.
First we need to handle sign comparison separately: if both numbers are
negative, we may compare them by flipping their signs, returning the opposite
answer. Patterns with the same exponent are compared according to their
mantissa.
Methods for Floats and Integers
In Python, the division operator / always returns a float. A floor division
(truncation) is made with the operator //. A module (remainder) operation
is given by the operator %. In addition, the method divmod(x,y) returns
both the quotient and remainder when dividing x by y:

## Complex Numbers

The complex data type is an (immutable) type that holds a pair of floats:
z = 3 + 4j. It has methods such as: z.real, z.imag, and z.conjugate().
Complex numbers are imported from the cmath module, which provides
complex number versions of most of the trigonometric and logarithmic functions that are in the math module, plus some complex number-specific functions such as: cmath.phase(), cmath.polar(), cmath.rect(), cmath.pi,
and cmath.e.

### The fraction Module

Python has the fraction module to deal with parts of a fraction. The
following snippet shows the basics methods of this module:

### The decimal Module

In the cases when we need exact decimal floating-point numbers, Python
includes an additional (immutable) float type, the decimal.Decimal. The
method takes an integer or a string as the argument (and starting from
Python 3.1, also floats, with the decimal.Decimal.from float() function).
This an efficient alternative when we do not want to deal with the rounding,
equality, and subtraction problems that floats come with:

While the math and cmath modules are not suitable for the decimal
module, its built-in functions, such as decimal.Decimal.exp(x), are enough
to most of the cases.