Python Numbers: Integers, Floats, and Complex for AI
Explore Python's numeric types: integers, floats, and complex numbers. Essential for data manipulation and algorithms in AI & machine learning.
1.3 Python Numbers
Python offers several built-in numeric types, providing flexibility for various computational tasks.
Built-in Number Types
Python has three fundamental built-in number types:
- Integers (
int
): Whole numbers, positive or negative, without a fractional part. - Floating-point numbers (
float
): Numbers with a fractional part, represented using a decimal point. - Complex numbers (
complex
): Numbers with a real and an imaginary part, written asa + bj
.
Additionally, Python has a bool
data type, which is a subtype of int
. Its two values, True
and False
, correspond to the integers 1
and 0
respectively.
Integers (int
)
An integer is any number that does not have a fractional part. For example, 5678
, -89
, and 0
are integers. Even 20.0
is considered a float because it includes a fractional part, even if that part is zero.
You can create integers in Python through:
- Literals: Directly writing the number.
- Expressions: Using arithmetic operations.
int()
function: Converting other types to integers.
Creating Integers
Literal:
a = 25
print(f"a: {a}, type: {type(a)}")
Expression:
b = 15
c = 35
d = b + c
print(f"b: {b}, type: {type(b)}")
print(f"d: {d}, type: {type(d)}")
Output:
a: 25, type: <class 'int'>
b: 15, type: <class 'int'>
d: 50, type: <class 'int'>
int()
Function:
The int()
function can convert strings or floating-point numbers to integers. When converting a float, the fractional part is truncated.
# From a float
a = int(45.9)
print(f"int(45.9): {a}, type: {type(a)}")
# From a string representing an integer
b = int("200")
print(f"int('200'): {b}, type: {type(b)}")
# From a string with a specified base (e.g., binary, octal, hex)
# See specific sections below for more on bases
Output:
int(45.9): 45, type: <class 'int'>
int('200'): 200, type: <class 'int'>
Different Number Bases
Python supports integers represented in binary, octal, and hexadecimal formats.
Binary Numbers
Binary numbers start with the prefix 0b
.
# Literal binary
a = 0b110
print(f"a = 0b110: {a}, type: {type(a)}")
# Converting a binary string to an integer
b = int("0b110101", 2) # The second argument '2' specifies base-2
print(f"b = int('0b110101', 2): {b}, type: {type(b)}")
Output:
a = 0b110: 6, type: <class 'int'>
b = int('0b110101', 2): 53, type: <class 'int'>
bin()
Function:
To get the binary representation of an integer as a string, use the bin()
function.
num = 53
binary_representation = bin(num)
print(f"Integer: {num}, Binary equivalent: {binary_representation}")
Output:
Integer: 53, Binary equivalent: 0b110101
Octal Numbers
Octal numbers use digits from 0 to 7 and start with the prefix 0o
.
# Literal octal
a = 0o123 # This represents 1*8^2 + 2*8^1 + 3*8^0 = 64 + 16 + 3 = 83
print(f"a = 0o123: {a}, type: {type(a)}")
# Converting an octal string to an integer
b = int('25', 8) # The second argument '8' specifies base-8 (2*8^1 + 5*8^0 = 16 + 5 = 21)
print(f"b = int('25', 8): {b}, type: {type(b)}")
# Addition with octal numbers
val1 = 0o65 # 6*8^1 + 5*8^0 = 48 + 5 = 53
val2 = int("0o40", 8) # 4*8^1 + 0*8^0 = 32
sum_val = val1 + val2
print(f"val1 = 0o65: {val1}, type: {type(val1)}")
print(f"val2 = int('0o40', 8): {val2}, type: {type(val2)}")
print(f"Addition: {sum_val}")
Output:
a = 0o123: 83, type: <class 'int'>
b = int('25', 8): 21, type: <class 'int'>
val1 = 0o65: 53, type: <class 'int'>
val2 = int('0o40', 8): 32, type: <class 'int'>
Addition: 85
oct()
Function:
To get the octal representation of an integer as a string, use the oct()
function.
num = 85
octal_representation = oct(num)
print(f"Integer: {num}, Octal equivalent: {octal_representation}")
Output:
Integer: 85, Octal equivalent: 0o125
Hexadecimal Numbers
Hexadecimal numbers use digits 0-9 and letters A-F (or a-f) and start with the prefix 0x
.
# Literal hexadecimal
a = 0xB4 # B is 11, 4 is 4. 11*16^1 + 4*16^0 = 176 + 4 = 180
print(f"a = 0xB4: {a}, type: {type(a)}")
# Converting a hex string to an integer
b = int('0X2a', 16) # 2*16^1 + a(10)*16^0 = 32 + 10 = 42
print(f"b = int('0X2a', 16): {b}, type: {type(b)}")
# Another example
num_string = "C2" # C is 12, 2 is 2. 12*16^1 + 2*16^0 = 192 + 2 = 194
number = int(num_string, 16)
print(f"Hexadecimal: {num_string}, Integer: {number}")
Output:
a = 0xB4: 180, type: <class 'int'>
b = int('0X2a', 16): 42, type: <class 'int'>
Hexadecimal: C2, Integer: 194
Invalid Hexadecimal String:
Attempting to convert a string with invalid hexadecimal characters will raise a ValueError
.
# num_string = "B3G001" # 'G' is not a valid hex digit
# print(int(num_string, 16))
Error Output:
ValueError: invalid literal for int() with base 16: 'B3G001'
hex()
Function:
To get the hexadecimal representation of an integer as a string, use the hex()
function.
num = 194
hex_representation = hex(num)
print(f"Integer: {num}, Hex equivalent: {hex_representation}")
Output:
Integer: 194, Hex equivalent: 0xc2
Mixed Base Representation: You can mix different base representations in expressions, and Python will handle the conversions internally.
decimal_num = 20
binary_num = 0b1010 # 10 in decimal
octal_num = 0o24 # 20 in decimal
hex_num = 0x14 # 20 in decimal
total_sum = decimal_num + binary_num + octal_num + hex_num
print(f"Sum of mixed bases: {total_sum}") # 20 + 10 + 20 + 20 = 70
Output:
Sum of mixed bases: 70
Floating-Point Numbers (float
)
Floating-point numbers have a fractional part. Examples include 8.88
, 0.123
, -7.77
, and -0.321
.
Scientific Notation
Floats can be represented using scientific notation, where E
or e
denotes "times 10 to the power of".
# 1.5 * 10^6
a = 1.5E6
print(f"a = 1.5E6: {a}")
# 7.12 * 10^-4
b = 7.12E-4
print(f"b = 7.12E-4: {b}")
# 1.11 * 10^2
c = 1.11E2
print(f"c = 1.11E2: {c}")
Output:
a = 1.5E6: 1500000.0
b = 7.12E-4: 0.000712
c = 1.11E2: 111.0
Creating Floats
You can create floats using expressions or the float()
function.
Using Expression:
x = 15.75
y = 3.15
z = x / y # Division in Python 3 always results in a float
print(f"c = x / y: {z}, type: {type(z)}")
Output:
c = x / y: 5.0, type: <class 'float'>
float()
Function:
The float()
function can convert integers, strings, or other numeric types to floating-point numbers.
# Without arguments, creates 0.0
a = float()
print(f"float(): {a}")
# From an integer
b = float(30)
print(f"float(30): {b}")
# From binary, octal, and hex representations (after conversion to integer)
c = float(0b11) # float(3)
d = float(0o12) # float(10)
e = float(0xF) # float(15)
print(f"From bases: {c}, {d}, {e}", sep=", ")
# From strings
f = float("-321.45")
g = float("2.34E03") # Represents 2.34 * 10^3
print(f"From strings: f={f}, g={g}")
Output:
float(): 0.0
float(30): 30.0
From bases: 3.0, 10.0, 15.0
From strings: f=-321.45, g=2340.0
Special Float Values
Floats can represent infinity and "Not a Number" (NaN).
# Infinity
inf_val = 1.00E400 # A number too large to represent as a standard float
print(f"Large number: {inf_val}, type: {type(inf_val)}")
inf_val_str = float("Infinity")
print(f"float('Infinity'): {inf_val_str}, type: {type(inf_val_str)}")
# NaN (Not a Number)
nan_val = float('nan')
print(f"float('nan'): {nan_val}")
Output:
Large number: inf, type: <class 'float'>
float('Infinity'): inf, type: <class 'float'>
float('nan'): nan
Complex Numbers (complex
)
A complex number has both a real part and an imaginary part. In mathematics, it's often written as $a + bj$, where $j$ is the imaginary unit ($\sqrt{-1}$). Python's complex
type directly supports this.
Creating Complex Numbers
You can create complex numbers using literals or the complex()
constructor.
# Using literal notation: real_part + imaginary_partj
num1 = 6 + 5j
print(f"Literal complex number: {num1}")
# Using the complex() constructor: complex(real_part, imaginary_part)
num2 = complex(2, -7) # Represents 2 - 7j
print(f"Complex() constructor: {num2}")
Output:
Literal complex number: (6+5j)
Complex() constructor: (2-7j)
Accessing Parts of Complex Numbers
Complex numbers in Python have attributes to access their real and imaginary components, and a method to get their conjugate.
z = 10 - 4j
# Accessing the real part
print(f"Real part of {z}: {z.real}")
# Accessing the imaginary part
print(f"Imaginary part of {z}: {z.imag}")
# Getting the complex conjugate (flips the sign of the imaginary part)
print(f"Conjugate of {z}: {z.conjugate()}")
Output:
Real part of (10-4j): 10.0
Imaginary part of (10-4j): -4.0
Conjugate of (10-4j): (10+4j)
Note: Comparison operators like <
, >
, <=
, >=
are not supported for complex numbers as they cannot be ordered.
Arithmetic with Complex Numbers
Python allows standard arithmetic operations (addition, subtraction, multiplication, division) directly with complex numbers.
a = 3 + 2j
b = 1 - 4j
print(f"Addition: {a} + {b} = {a + b}")
print(f"Subtraction: {a} - {b} = {a - b}")
print(f"Multiplication: {a} * {b} = {a * b}")
print(f"Division: {a} / {b} = {a / b}")
# The magnitude (or modulus) of a complex number z = a + bj is sqrt(a^2 + b^2)
print(f"Magnitude of (3 + 4j): {abs(3 + 4j)}") # sqrt(3^2 + 4^2) = sqrt(9 + 16) = sqrt(25) = 5.0
Output:
Addition: (3+2j) + (1-4j) = (4-2j)
Subtraction: (3+2j) - (1-4j) = (2+6j)
Multiplication: (3+2j) * (1-4j) = (11-10j)
Division: (3+2j) / (1-4j) = (-0.2+0.8j)
Magnitude of (3 + 4j): 5.0
The math
Module
The math
module provides access to mathematical functions and constants defined by the C standard library. It's essential for advanced mathematical operations.
import math
Mathematical Constants
The module includes useful mathematical constants:
Constant | Description | Example Value |
---|---|---|
math.pi | The ratio of a circle's circumference to its diameter (π) | $\approx 3.14159$ |
math.e | Euler's number (base of natural logarithms) | $\approx 2.71828$ |
math.tau | Twice the value of math.pi ($\tau = 2\pi$) | $\approx 6.28318$ |
print(f"Value of pi: {math.pi}")
print(f"Value of e: {math.e}")
print(f"Value of tau: {math.tau}")
Power and Logarithmic Functions
Function | Description |
---|---|
math.pow(x, y) | Returns x raised to the power of y . |
math.sqrt(x) | Returns the square root of x . |
math.exp(x) | Returns e raised to the power of x . |
math.log(x, base) | Returns the logarithm of x to the given base . |
math.log10(x) | Returns the base-10 logarithm of x . |
math.log2(x) | Returns the base-2 logarithm of x . |
print(f"2 raised to the power of 5: {math.pow(2, 5)}")
print(f"Square root of 49: {math.sqrt(49)}")
print(f"e raised to the power of 1: {math.exp(1)}")
print(f"Logarithm of 100 to base 10: {math.log(100, 10)}")
print(f"Logarithm of 100 to base e: {math.log(100)}") # Equivalent to math.log(100, math.e)
Trigonometric Functions
These functions expect angles in radians.
Function | Description |
---|---|
math.sin(x) | Sine of angle x (in radians). |
math.cos(x) | Cosine of angle x (in radians). |
math.tan(x) | Tangent of angle x (in radians). |
math.radians(x) | Converts angle x from degrees to radians. |
angle_deg = 60
angle_rad = math.radians(angle_deg)
print(f"Sine of {angle_deg} degrees ({angle_rad:.2f} rad): {math.sin(angle_rad)}")
print(f"Cosine of {angle_deg} degrees ({angle_rad:.2f} rad): {math.cos(angle_rad)}")
print(f"Tangent of {angle_deg} degrees ({angle_rad:.2f} rad): {math.tan(angle_rad)}")
Inverse Trigonometric Functions
These functions return angles in radians.
Function | Description |
---|---|
math.asin(x) | Inverse sine (arcsin). |
math.acos(x) | Inverse cosine (arccos). |
math.atan(x) | Inverse tangent (arctan). |
math.degrees(x) | Converts angle x from radians to degrees. |
# Finding the angle whose cosine is 0.5
angle_in_radians = math.acos(0.5)
angle_in_degrees = math.degrees(angle_in_radians)
print(f"Angle (in degrees) whose cosine is 0.5: {angle_in_degrees}")
Hyperbolic Functions
These functions are analogous to trigonometric functions but are based on the hyperbola.
Function | Description |
---|---|
math.sinh(x) | Hyperbolic sine. |
math.cosh(x) | Hyperbolic cosine. |
math.tanh(x) | Hyperbolic tangent. |
print(f"Hyperbolic sine of 2: {math.sinh(2)}")
Special Functions
Function | Description |
---|---|
math.factorial(n) | Factorial of non-negative integer n . |
math.gcd(a, b) | Greatest Common Divisor of integers a and b . |
math.lcm(a, b) | Least Common Multiple of integers a and b (Python 3.9+). |
math.fabs(x) | Absolute value of x as a float. |
print(f"Factorial of 5: {math.factorial(5)}")
print(f"GCD of 36 and 60: {math.gcd(36, 60)}")
print(f"Absolute value of -7.5: {math.fabs(-7.5)}")
Rounding and Numeric Utilities
Function | Description |
---|---|
math.ceil(x) | Rounds x up to the nearest integer. |
math.floor(x) | Rounds x down to the nearest integer. |
math.trunc(x) | Truncates x by removing the fractional part. |
math.modf(x) | Splits x into its fractional and integer parts, returning them as a tuple (fractional, integer) . Both parts have the same sign as x . |
print(f"Ceiling of 5.4: {math.ceil(5.4)}") # Rounds up to 6
print(f"Floor of 5.4: {math.floor(5.4)}") # Rounds down to 5
print(f"Truncate of 5.9: {math.trunc(5.9)}") # Removes decimal, result is 5
print(f"Split 7.25: {math.modf(7.25)}") # Returns (0.25, 7.0)
print(f"Split -7.25: {math.modf(-7.25)}") # Returns (-0.25, -7.0)
The random
Module
The random
module is used for generating pseudo-random numbers and performing random actions, such as shuffling lists or selecting random elements. It's widely used in simulations, games, and data sampling.
import random
Random Number Generation
Function | Description |
---|---|
random.random() | Returns a random float in the interval [0.0, 1.0) . |
random.uniform(a, b) | Returns a random float N such that a <= N <= b for a <= b and b <= N <= a for b < a . |
random.randint(a, b) | Returns a random integer N such that a <= N <= b . Includes both endpoints. |
random.randrange(start, stop[, step]) | Returns a randomly selected element from range(start, stop, step) . |
print(f"Random float [0.0, 1.0): {random.random()}")
print(f"Random float between 10 and 20: {random.uniform(10, 20)}")
print(f"Random integer between 5 and 10: {random.randint(5, 10)}")
print(f"Random integer from range(0, 100, 10) (multiples of 10): {random.randrange(0, 100, 10)}")
Working with Lists (Sequences)
Function | Description |
---|---|
random.choice(seq) | Returns a random element from a non-empty sequence seq . |
random.shuffle(seq) | Shuffles the sequence seq in-place. |
random.sample(seq, k) | Returns a list of k unique elements chosen from the sequence seq . |
fruits = ['apple', 'banana', 'cherry', 'date', 'elderberry']
print(f"Random choice from fruits: {random.choice(fruits)}")
# Shuffle the list in-place
print(f"Original fruits: {fruits}")
random.shuffle(fruits)
print(f"Shuffled fruits: {fruits}")
# Select 2 unique items from the shuffled list
print(f"2 unique random samples: {random.sample(fruits, 2)}")
Setting a Seed
To ensure reproducible results for random operations (e.g., for testing or debugging), you can set the random seed. The same seed will always produce the same sequence of "random" numbers.
random.seed(42) # Setting the seed to 42
print(f"Random integer after seed 42: {random.randint(1, 10)}")
random.seed(42) # Resetting the seed to 42
print(f"Another random integer after resetting seed 42: {random.randint(1, 10)}") # Will be the same as the previous line
Output:
Random integer after seed 42: 6
Another random integer after resetting seed 42: 6
Python Data Types for AI & Machine Learning Explained
Master Python data types, the core of AI & Machine Learning development. Understand dynamic typing and variable instances for efficient data handling in Python.
Python Type Casting: Implicit & Explicit Conversion Explained
Learn Python type casting (conversion) for data science & AI. Understand implicit and explicit casting to convert strings to numbers, crucial for LLM and machine learning data processing.