Skip to content

C++ Numbers

C++ provides various fundamental data types for representing numbers, including integers (short, int, long, long long, potentially signed or unsigned) and floating-point numbers (float, double, long double). The choice depends on the required range and precision.

You define numeric variables by specifying the type and name, and it’s crucial to initialize them.

#include <iostream>
#include <limits> // For numeric limits
int main() {
// Integer types
short smallNum {150};
int standardInt {-50000};
long long largeInt {1234567890123LL}; // LL suffix for long long
unsigned int positiveOnly {400000};
// Floating-point types
float price {99.95f}; // f suffix for float
double pi {3.1415926535};
long double highPrecisionPi {3.141592653589793238L}; // L suffix for long double
// Printing numbers
std::cout << "short: " << smallNum << std::endl;
std::cout << "int: " << standardInt << std::endl;
std::cout << "long long: " << largeInt << std::endl;
std::cout << "unsigned int: " << positiveOnly << std::endl;
std::cout << "float: " << price << std::endl;
std::cout << "double: " << pi << std::endl;
// Ensure high precision output for long double if needed
std::cout.precision(std::numeric_limits<long double>::max_digits10);
std::cout << "long double: " << highPrecisionPi << std::endl;
return 0;
}

Output (floating point precision may vary slightly):

short: 150
int: -50000
long long: 1234567890123
unsigned int: 400000
float: 99.95
double: 3.14159
long double: 3.141592653589793238

C++ supports standard arithmetic operators (+, -, *, /, %). For more advanced mathematical functions, include the <cmath> header.

FunctionDescription
std::sqrt(x)Computes the square root of x.
std::pow(base, exp)Computes base raised to the power exp.
std::sin(x), std::cos(x), std::tan(x)Trigonometric functions (angle x in radians).
std::log(x)Computes the natural logarithm (base e) of x.
std::log10(x)Computes the common logarithm (base 10) of x.
std::abs(x)Computes the absolute value of an integer x (from <cstdlib>).
std::fabs(x)Computes the absolute value of a floating-point x (from <cmath>).
std::ceil(x)Rounds x up to the nearest integer (returns double).
std::floor(x)Rounds x down to the nearest integer (returns double).
std::round(x)Rounds x to the nearest integer (returns double, C++11).
std::hypot(x, y)Computes the square root of (x² + y²) without intermediate overflow/underflow (C++11).

Example using <cmath>:

#include <iostream>
#include <cmath> // Include for math functions
#include <cstdlib> // For std::abs
int main() {
double d = -200.374;
float f = 230.47f;
int i = -1000;
std::cout << "fabs(d): " << std::fabs(d) << std::endl;
std::cout << "abs(i): " << std::abs(i) << std::endl;
std::cout << "floor(d): " << std::floor(d) << std::endl;
std::cout << "ceil(d): " << std::ceil(d) << std::endl;
std::cout << "sqrt(f): " << std::sqrt(f) << std::endl;
std::cout << "pow(5.0, 3.0): " << std::pow(5.0, 3.0) << std::endl;
return 0;
}

Output:

fabs(d): 200.374
abs(i): 1000
floor(d): -201
ceil(d): -200
sqrt(f): 15.1812
pow(5.0, 3.0): 125

Generating high-quality random numbers is crucial in many applications (simulations, games, cryptography). The older C-style rand() and srand() functions (from <cstdlib>) are generally discouraged in modern C++ because they often produce low-quality pseudo-random numbers and are not thread-safe.

The <random> header (introduced in C++11) provides a much better framework:

  1. Random Number Engines: Generate sequences of pseudo-random bits (e.g., std::mt19937 - Mersenne Twister, a high-quality general-purpose engine).
  2. Random Number Distributions: Map the engine’s output to specific statistical distributions (e.g., uniform integer std::uniform_int_distribution, uniform real std::uniform_real_distribution, normal std::normal_distribution).
  3. Seeding: Engines need to be seeded (initialized) to produce different sequences each time. Using std::random_device is a common way to get a non-deterministic seed.

Example using <random>:

#include <iostream>
#include <random> // Include for modern random number generation
#include <vector>
int main() {
// 1. Seed the random number engine (preferably once per application run)
std::random_device rd; // Obtains a non-deterministic seed from the hardware/OS
std::mt19937 engine(rd()); // Mersenne Twister engine seeded with rd()
// 2. Define distributions
std::uniform_int_distribution<int> uniform_dist_int(1, 100); // Integers between 1 and 100 (inclusive)
std::uniform_real_distribution<double> uniform_dist_real(0.0, 1.0); // Doubles between 0.0 and 1.0 (exclusive of 1.0)
std::normal_distribution<double> normal_dist(50.0, 10.0); // Mean=50, Standard Deviation=10
// 3. Generate random numbers using the engine and distributions
std::cout << "Uniform integers (1-100):" << std::endl;
for (int i = 0; i < 5; ++i) {
std::cout << uniform_dist_int(engine) << " ";
}
std::cout << std::endl;
std::cout << "\nUniform doubles (0.0-1.0):" << std::endl;
for (int i = 0; i < 5; ++i) {
std::cout << uniform_dist_real(engine) << " ";
}
std::cout << std::endl;
std::cout << "\nNormally distributed doubles (mean=50, stddev=10):" << std::endl;
for (int i = 0; i < 5; ++i) {
std::cout << normal_dist(engine) << " ";
}
std::cout << std::endl;
return 0;
}

Sample Output (values will differ on each run):

Uniform integers (1-100):
75 15 68 91 3
Uniform doubles (0.0-1.0):
0.888989 0.194441 0.686665 0.241961 0.542765
Normally distributed doubles (mean=50, stddev=10):
46.5876 57.8495 39.9173 52.5858 61.5401

Recommendation: Always prefer the <random> library over rand()/srand() for random number generation in C++.