In Python, numbers are objects just like strings, lists, and dictionaries. This means they have built-in methods and attributes. Additionally, numbers are immutable, meaning their values cannot be changed once created. Instead, new objects are created when operations are performed.
x = 10
print(id(x))  # Memory address of x
x = x + 5
print(id(x))  # Different memory address, because x now refers to a new object
Since numbers are immutable, modifying them does not affect the original value but instead creates a new object.
x = 10
print(id(x)) # Memory address of x
print(id(10)) # The same memory address because Python doesn't need to create the same object twice
y = 10
print(id(y)) # The same memory address
Numeric Types in Python
Python provides three primary numeric types:
- Integers (int): Whole numbers (e.g.,1,42,-1000).
- Floating-Point Numbers (float): Numbers with decimals (e.g.,3.14,2.71,-0.001).
- Complex Numbers (complex): Numbers with a real and imaginary part (e.g.,3 + 4j).
Checking the Type of a Number
You can check the type of a number using type():
print(type(42))     # Output: <class 'int'>
print(type(3.14))   # Output: <class 'float'>
print(type(2 + 3j)) # Output: <class 'complex'>
print(type(42) is int)     # True
print(type(3.14) is float)   # True
print(type(2 + 3j) is complex) # True
Integer and Floating-Point Arithmetic
Python provides various operators for performing numerical calculations.
Basic Arithmetic Operations
a = 10
b = 3
print(a + b)   # Addition -> Output: 13
print(a - b)   # Subtraction -> Output: 7
print(a * b)   # Multiplication -> Output: 30
print(a / b)   # Floating-point division -> Output: 3.3333333333333335
print(a // b)  # Floor division -> Output: 3
print(a % b)   # Modulus (remainder) -> Output: 1
print(a ** b)  # Exponentiation -> Output: 1000
Floating-Point Division (/)
The / operator always returns a float, even if the result is a whole number.
print(10 / 2)   # Output: 5.0 (float, not int)
print(7 / 2)    # Output: 3.5
Floor Division (//)
The // operator performs division but rounds down to the nearest whole number. It always returns an integer if both operands are integers and a float if at least one operand is a float.
print(10 // 3)   # Output: 3
print(-10 // 3)  # Output: -4 (rounded down, not towards zero)
print(10.5 // 3) # Output: 3.0
Exponentiation (**)
The ** operator is used to calculate powers.
print(2 ** 3)    # Output: 8 (2^3)
print(5 ** 0.5)  # Output: 2.23606797749979 (square root of 5)
Converting Between Number Types
Python allows easy conversion between number types using int(), float(), and complex().
x = 10         # Integer
y = 3.14       # Float
z = "42"       # String
print(float(x))  # Convert int to float -> Output: 10.0
print(int(y))    # Convert float to int -> Output: 3 (truncates, does not round)
print(int(z))    # Convert string to int -> Output: 42
print(complex(x)) # Convert int to complex -> Output: (10+0j)
Built-in Math Functions
Python provides several built-in functions for working with numbers.
print(abs(-7))    # Absolute value -> Output: 7
print(round(3.14159, 2))  # Rounding -> Output: 3.14
print(pow(2, 3))  # Equivalent to 2 ** 3 -> Output: 8
For advanced math operations, Python’s math module provides additional functionality.
import math
print(math.sqrt(25))   # Square root -> Output: 5.0
print(math.factorial(5)) # Factorial -> Output: 120
print(math.log(100, 10)) # Logarithm base 10 -> Output: 2.0
Working with Large Numbers
Python supports arbitrarily large integers. Unlike many other languages, there is no fixed limit on integer size (except for available memory).
big_number = 10 ** 100  # 10 raised to the power of 100
print(big_number)       # Output: A very large number
print(type(big_number)) # Output: <class 'int'>
For handling large floating-point numbers, Python supports the decimal module, which provides arbitrary-precision arithmetic.
from decimal import Decimal
x = Decimal("0.1") + Decimal("0.2")
print(x)  # Output: 0.3 (precise calculation)
Boolean Operations with Numbers
Since True and False are subclasses of int, they can participate in numerical operations.
print(True + True)  # Output: 2 (1 + 1)
print(False * 10)   # Output: 0 (0 * 10)
However, using boolean values in numeric operations is not a recommended practice unless specifically required.
Common Pitfalls and Best Practices
- 
Floating-Point Precision Issues - Floating-point arithmetic is not always exact due to binary representation.
 print(0.1 + 0.2) # Output: 0.30000000000000004 (unexpected result)- Use the decimalmodule for precise calculations when needed.
 
- 
Integer Division Difference - Be aware that /always returns a float, even if dividing two integers.
 print(10 / 2) # Output: 5.0 (not int)
- Be aware that 
- 
Avoid Unnecessary Type Conversions - Converting between types excessively can lead to performance overhead.
 num = 10 print(float(int(str(num)))) # Inefficient!
- 
Use mathfor Complex Computations- Instead of x ** 0.5, prefermath.sqrt(x)for better performance.
 
- Instead of 
Conclusion
Numbers in Python are powerful, flexible, and behave like objects while being immutable. Whether you're performing simple calculations or handling complex numerical data, Python provides a wide range of tools to make it easy. Understanding number types, arithmetic operations, division nuances, and best practices ensures you write efficient and error-free code.
