# Numeric data types

Python is a dynamically typed language. The interpreter infers the data type of a value based on pre-determined rules. In the previous chapter, **string** values were coded using single quotes around a sequence of characters. Similarly, there are rules by which you can declare different numeric data types.

## int

Integer numbers are made up of digits `0`

to `9`

and can be prefixed with **unary** operators like `+`

or `-`

. There is no restriction to the size of numbers that can be used, only limited by the memory available on your system. Here's some examples:

```
>>> 42
42
>>> 0
0
>>> +100
100
>>> -5
-5
```

For readability purposes, you can use underscores in between the digits.

```
>>> 1_000_000_000
1000000000
```

Underscore cannot be used as the first or last character, and cannot be used consecutively.

## float

Here's some examples for floating-point numbers.

```
>>> 3.14
3.14
>>> -1.12
-1.12
```

Python also supports the exponential notation. See wikipedia: E scientific notation for details about this form of expressing numbers.

```
>>> 543.15e20
5.4315e+22
>>> 1.5e-5
1.5e-05
```

Unlike integers, floating-point numbers have a limited precision. While displaying very small or very large floating-point numbers, Python will automatically convert them to the exponential notation.

```
>>> 0.0000000001234567890123456789
1.2345678901234568e-10
>>> 31415926535897935809629384623048923.649234324234
3.1415926535897936e+34
```

You might also get seemingly strange results as shown below. See docs.python: Floating Point Arithmetic Issues and Limitations and stackoverflow: Is floating point math broken? for details and workarounds.

```
>>> 3.14 + 2
5.140000000000001
```

## Arithmetic operators

All arithmetic operators you'd typically expect are available. If any operand is a floating-point number, result will be of `float`

data type. Use `+`

for addition, `-`

for subtraction, `*`

for multiplication and `**`

for exponentiation. As mentioned before, REPL is quite useful for learning purposes. It makes for a good calculator for number crunching as well. You can also use `_`

to refer to the result of the previous expression (this is applicable only in the REPL, not in Python scripts).

```
>>> 25 + 17
42
>>> 10 - 8
2
>>> 25 * 3.3
82.5
>>> 32 ** 42
1645504557321206042154969182557350504982735865633579863348609024
>>> 5 + 2
7
>>> _ * 3
21
```

There are two operators for division. Use `/`

if you want a floating-point result. Using `//`

between two integers will give only the integer portion of the result (no rounding).

```
>>> 4.5 / 1.5
3.0
>>> 5 / 3
1.6666666666666667
>>> 5 // 3
1
```

Use modulo operator `%`

to get the remainder. Sign of the result is same as the sign of the second operand.

```
>>> 5 % 3
2
>>> -5 % 3
1
>>> 5 % -3
-1
>>> 6.5 % -3
-2.5
```

See docs.python: Binary arithmetic operations and stackoverflow: modulo operation on negative numbers for more details.

## Operator precedence

Arithmetic operator precedence follows the familiar **PEMDAS** or **BODMAS** abbreviations. Precedence, higher to lower is listed below:

- Expression inside parentheses
- exponentiation
- multiplication, division, modulo
- addition, subtraction

Expression is evaluated left-to-right when operators have the same precedence. Unary operator precedence is between exponentiation and multiplication/division operators. See docs.python: Operator precedence for complete details.

## Integer formats

The integer examples so far have been coded using base 10, i.e. **decimal** format. Python has provision for representing **binary**, **octal** and **hexadecimal** formats as well. To distinguish between these different formats, a prefix is used:

`0b`

or`0B`

for binary`0o`

or`0O`

for octal`0x`

or`0X`

for hexadecimal

All four formats fall under the `int`

data type. Python displays them in decimal format by default. Underscores can be used for readability for any of these formats.

```
>>> 0b1000_1111
143
>>> 0o10
8
>>> 0x10
16
>>> 5 + 0xa
15
```

Decimal format numbers cannot be prefixed by `0`

, other than `0`

itself.

```
>>> 00000
0
>>> 09
File "<stdin>", line 1
09
^
SyntaxError: leading zeros in decimal integer literals are not permitted;
use an 0o prefix for octal integers
```

If code execution hits a snag, you'll get an error message along with the code snippet that the interpreter thinks caused the issue. In Python parlance, an **exception** has occurred. The exception has a name (`SyntaxError`

in the above example) followed by the error message. See Exception handling chapter for more details.

## Other numeric types

Python's standard data type also includes complex type (imaginary part is suffixed with the character `j`

). Others like `decimal`

and `fractions`

are provided as modules.

Some of the numeric types can have alphabets like

`e`

,`b`

,`j`

, etc in their values. As Python is a dynamically typed language, you cannot use variable names beginning with a number. Otherwise, it would be impossible to evaluate an expression like`result = input_value + 0x12 - 2j`

.

There are many third-party libraries that are useful for number crunching in mathematical context, engineering applications, etc. See my list py_resources: Scientific computing for curated resources.