C++ Numbers and Numerics
Overview
Numbers and numeric operations are the foundation of programming. C++ provides rich numeric types and mathematical function libraries, supporting everything from basic arithmetic operations to complex mathematical calculations. This chapter introduces numeric types, mathematical operations, precision handling, and related best practices.
🔢 Numeric Types Overview
Integer Type Ranges
cpp
#include <iostream>
#include <climits>
int main() {
std::cout << "=== Integer Type Ranges ===" << std::endl;
// Signed integer types
std::cout << "char: " << (int)CHAR_MIN << " to " << (int)CHAR_MAX << std::endl;
std::cout << "short: " << SHRT_MIN << " to " << SHRT_MAX << std::endl;
std::cout << "int: " << INT_MIN << " to " << INT_MAX << std::endl;
std::cout << "long long: " << LLONG_MIN << " to " << LLONG_MAX << std::endl;
// Unsigned integer types
std::cout << "\nUnsigned type maximum values:" << std::endl;
std::cout << "unsigned int: " << UINT_MAX << std::endl;
std::cout << "unsigned long long: " << ULLONG_MAX << std::endl;
// Type sizes
std::cout << "\nType sizes (bytes):" << std::endl;
std::cout << "int: " << sizeof(int) << std::endl;
std::cout << "long: " << sizeof(long) << std::endl;
std::cout << "long long: " << sizeof(long long) << std::endl;
return 0;
}Floating Point Type Characteristics
cpp
#include <iostream>
#include <cfloat>
#include <iomanip>
int main() {
std::cout << "=== Floating Point Type Characteristics ===" << std::endl;
// Precision digits
std::cout << "float precision: " << FLT_DIG << " digits" << std::endl;
std::cout << "double precision: " << DBL_DIG << " digits" << std::endl;
// Type sizes
std::cout << "float: " << sizeof(float) << " bytes" << std::endl;
std::cout << "double: " << sizeof(double) << " bytes" << std::endl;
// Precision demonstration
std::cout << "\n=== Precision Demonstration ===" << std::endl;
float f = 1.23456789f;
double d = 1.23456789;
std::cout << std::setprecision(10);
std::cout << "float: " << f << std::endl;
std::cout << "double: " << d << std::endl;
return 0;
}➕ Basic Mathematical Operations
Arithmetic Operators
cpp
#include <iostream>
int main() {
std::cout << "=== Basic Arithmetic Operations ===" << std::endl;
int a = 15, b = 4;
double x = 15.0, y = 4.0;
// Integer operations
std::cout << "Integer operations (a=" << a << ", b=" << b << "):" << std::endl;
std::cout << "a + b = " << (a + b) << std::endl;
std::cout << "a - b = " << (a - b) << std::endl;
std::cout << "a * b = " << (a * b) << std::endl;
std::cout << "a / b = " << (a / b) << " (integer division)" << std::endl;
std::cout << "a % b = " << (a % b) << " (modulo)" << std::endl;
// Floating point operations
std::cout << "\nFloating point operations (x=" << x << ", y=" << y << "):" << std::endl;
std::cout << "x / y = " << (x / y) << " (floating point division)" << std::endl;
// Compound assignment operators
std::cout << "\n=== Compound Assignment Operators ===" << std::endl;
int num = 10;
std::cout << "Initial value: " << num << std::endl;
num += 5; std::cout << "num += 5: " << num << std::endl;
num -= 3; std::cout << "num -= 3: " << num << std::endl;
num *= 2; std::cout << "num *= 2: " << num << std::endl;
num /= 4; std::cout << "num /= 4: " << num << std::endl;
// Increment and decrement
std::cout << "\n=== Increment and Decrement Operators ===" << std::endl;
int i = 5;
std::cout << "i++ = " << i++ << " (post-increment)" << std::endl;
std::cout << "++i = " << ++i << " (pre-increment)" << std::endl;
return 0;
}Mathematical Function Library
cpp
#include <iostream>
#include <cmath>
#include <iomanip>
int main() {
std::cout << std::fixed << std::setprecision(4);
std::cout << "=== Basic Mathematical Functions ===" << std::endl;
double num = 16.0;
std::cout << "sqrt(16): " << sqrt(num) << std::endl;
std::cout << "pow(2, 4): " << pow(2, 4) << std::endl;
std::cout << "exp(1): " << exp(1) << std::endl;
std::cout << "log(10): " << log(10) << std::endl;
std::cout << "\n=== Trigonometric Functions ===" << std::endl;
double angle = M_PI / 4; // 45 degrees
std::cout << "sin(π/4): " << sin(angle) << std::endl;
std::cout << "cos(π/4): " << cos(angle) << std::endl;
std::cout << "tan(π/4): " << tan(angle) << std::endl;
std::cout << "\n=== Rounding Functions ===" << std::endl;
double decimal = 3.7;
std::cout << "Original value: " << decimal << std::endl;
std::cout << "ceil: " << ceil(decimal) << std::endl;
std::cout << "floor: " << floor(decimal) << std::endl;
std::cout << "round: " << round(decimal) << std::endl;
std::cout << "\n=== Other Functions ===" << std::endl;
std::cout << "abs(-5): " << abs(-5) << std::endl;
std::cout << "fabs(-5.5): " << fabs(-5.5) << std::endl;
std::cout << "fmod(7.5, 2.5): " << fmod(7.5, 2.5) << std::endl;
return 0;
}🎯 Numeric Precision and Comparison
Floating Point Precision Issues
cpp
#include <iostream>
#include <iomanip>
#include <cmath>
int main() {
std::cout << std::fixed << std::setprecision(20);
std::cout << "=== Floating Point Precision Issues ===" << std::endl;
// Typical floating point precision issue
double a = 0.1;
double b = 0.2;
double sum = a + b;
std::cout << "0.1 + 0.2 = " << sum << std::endl;
std::cout << "Equals 0.3? " << (sum == 0.3 ? "Yes" : "No") << std::endl;
// Safe floating point comparison
std::cout << "\n=== Safe Floating Point Comparison ===" << std::endl;
auto isEqual = [](double x, double y, double epsilon = 1e-9) {
return std::abs(x - y) < epsilon;
};
std::cout << "Using epsilon comparison:" << std::endl;
std::cout << "0.1 + 0.2 ≈ 0.3? " << (isEqual(sum, 0.3) ? "Yes" : "No") << std::endl;
return 0;
}Rounding and Formatting
cpp
#include <iostream>
#include <iomanip>
#include <cmath>
// Custom rounding function
double roundToDecimalPlaces(double value, int decimalPlaces) {
double factor = std::pow(10.0, decimalPlaces);
return std::round(value * factor) / factor;
}
int main() {
std::cout << std::fixed;
std::cout << "=== Rounding Methods ===" << std::endl;
double value = 2.675;
std::cout << std::setprecision(3) << "Original value: " << value << std::endl;
std::cout << std::setprecision(2);
std::cout << "Round to 2 decimal places: " << roundToDecimalPlaces(value, 2) << std::endl;
std::cout << "Round up: " << std::ceil(value * 100) / 100 << std::endl;
std::cout << "Round down: " << std::floor(value * 100) / 100 << std::endl;
std::cout << "\n=== Formatting Output ===" << std::endl;
double pi = 3.141592653589793;
std::cout << "2 decimal places: " << std::setprecision(2) << pi << std::endl;
std::cout << "4 decimal places: " << std::setprecision(4) << pi << std::endl;
std::cout << "Scientific notation: " << std::scientific << pi << std::endl;
return 0;
}🔀 Numeric Conversions
Type Conversions and String Conversions
cpp
#include <iostream>
#include <string>
int main() {
std::cout << "=== Numeric Type Conversions ===" << std::endl;
// Implicit conversion
int i = 42;
double d = i; // int to double (safe)
std::cout << "int to double: " << i << " -> " << d << std::endl;
double d2 = 3.14159;
int i2 = static_cast<int>(d2); // Explicit conversion
std::cout << "double to int: " << d2 << " -> " << i2 << std::endl;
// String conversions
std::cout << "\n=== String Conversions ===" << std::endl;
// Numeric to string
int num = 123;
double decimal = 45.67;
std::string str1 = std::to_string(num);
std::string str2 = std::to_string(decimal);
std::cout << "to_string: " << num << " -> \"" << str1 << "\"" << std::endl;
std::cout << "to_string: " << decimal << " -> \"" << str2 << "\"" << std::endl;
// String to numeric
std::string strNum = "987";
std::string strDecimal = "12.34";
try {
int converted1 = std::stoi(strNum);
double converted2 = std::stod(strDecimal);
std::cout << "stoi: \"" << strNum << "\" -> " << converted1 << std::endl;
std::cout << "stod: \"" << strDecimal << "\" -> " << converted2 << std::endl;
}
catch (const std::exception& e) {
std::cout << "Conversion error: " << e.what() << std::endl;
}
return 0;
}🎲 Random Number Generation
Modern C++ Random Numbers
cpp
#include <iostream>
#include <random>
#include <vector>
#include <algorithm>
int main() {
std::cout << "=== Modern C++ Random Number Generation ===" << std::endl;
// Random number engine
std::random_device rd; // Hardware random number
std::mt19937 gen(rd()); // Mersenne Twister generator
// Uniform integer distribution
std::cout << "=== Uniform Integer Distribution (1-10) ===" << std::endl;
std::uniform_int_distribution<> intDist(1, 10);
for (int i = 0; i < 10; i++) {
std::cout << intDist(gen) << " ";
}
std::cout << std::endl;
// Uniform real distribution
std::cout << "\n=== Uniform Real Distribution (0.0-1.0) ===" << std::endl;
std::uniform_real_distribution<> realDist(0.0, 1.0);
for (int i = 0; i < 5; i++) {
std::cout << std::fixed << std::setprecision(4) << realDist(gen) << " ";
}
std::cout << std::endl;
// Random shuffle
std::cout << "\n=== Random Shuffle ===" << std::endl;
std::vector<int> deck = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
std::cout << "Original: ";
for (int card : deck) std::cout << card << " ";
std::cout << std::endl;
std::shuffle(deck.begin(), deck.end(), gen);
std::cout << "Shuffled: ";
for (int card : deck) std::cout << card << " ";
std::cout << std::endl;
return 0;
}Random Number Application Examples
cpp
#include <iostream>
#include <random>
#include <map>
// Random number utility class
class RandomUtils {
private:
std::mt19937 gen_;
public:
RandomUtils() : gen_(std::random_device{}()) {}
int randomInt(int min, int max) {
std::uniform_int_distribution<> dist(min, max);
return dist(gen_);
}
double randomReal(double min, double max) {
std::uniform_real_distribution<> dist(min, max);
return dist(gen_);
}
bool randomBool(double probability = 0.5) {
std::bernoulli_distribution dist(probability);
return dist(gen_);
}
};
int main() {
RandomUtils random;
std::cout << "=== Random Number Application Examples ===" << std::endl;
// Simulate dice
std::cout << "=== Simulate Dice Rolling ===" << std::endl;
std::map<int, int> diceResults;
for (int i = 0; i < 600; i++) {
int roll = random.randomInt(1, 6);
diceResults[roll]++;
}
for (const auto& [face, count] : diceResults) {
std::cout << "Face " << face << ": " << count << " times" << std::endl;
}
// Probability events
std::cout << "\n=== Probability Event Simulation ===" << std::endl;
int successCount = 0;
int trials = 1000;
double successProbability = 0.3;
for (int i = 0; i < trials; i++) {
if (random.randomBool(successProbability)) {
successCount++;
}
}
double actualProbability = static_cast<double>(successCount) / trials;
std::cout << "Expected probability: " << successProbability << std::endl;
std::cout << "Actual probability: " << actualProbability << std::endl;
return 0;
}📊 Numeric Calculation Examples
Simple Numeric Algorithms
cpp
#include <iostream>
#include <cmath>
#include <vector>
// Calculate mean
double calculateMean(const std::vector<double>& data) {
double sum = 0.0;
for (double value : data) {
sum += value;
}
return sum / data.size();
}
// Calculate standard deviation
double calculateStandardDeviation(const std::vector<double>& data) {
double mean = calculateMean(data);
double sumSquaredDiff = 0.0;
for (double value : data) {
double diff = value - mean;
sumSquaredDiff += diff * diff;
}
return std::sqrt(sumSquaredDiff / data.size());
}
// Find minimum and maximum values
std::pair<double, double> findMinMax(const std::vector<double>& data) {
double minVal = data[0];
double maxVal = data[0];
for (double value : data) {
if (value < minVal) minVal = value;
if (value > maxVal) maxVal = value;
}
return {minVal, maxVal};
}
int main() {
std::cout << "=== Numeric Calculation Examples ===" << std::endl;
std::vector<double> data = {1.2, 3.4, 2.1, 4.8, 2.9, 3.7, 1.8, 4.2, 3.1, 2.6};
std::cout << "Data: ";
for (double value : data) {
std::cout << value << " ";
}
std::cout << std::endl;
// Statistical calculations
double mean = calculateMean(data);
double stdDev = calculateStandardDeviation(data);
auto [minVal, maxVal] = findMinMax(data);
std::cout << std::fixed << std::setprecision(3);
std::cout << "Mean: " << mean << std::endl;
std::cout << "Standard deviation: " << stdDev << std::endl;
std::cout << "Minimum: " << minVal << std::endl;
std::cout << "Maximum: " << maxVal << std::endl;
std::cout << "Range: " << (maxVal - minVal) << std::endl;
return 0;
}📋 Numeric Processing Best Practices
Numeric Programming Guide
cpp
#include <iostream>
#include <limits>
#include <cmath>
int main() {
std::cout << "=== Numeric Programming Best Practices ===" << std::endl;
// 1. Avoid division by zero
auto safeDivide = [](double a, double b) -> double {
if (std::abs(b) < std::numeric_limits<double>::epsilon()) {
std::cout << "Warning: Divisor is close to zero" << std::endl;
return std::numeric_limits<double>::infinity();
}
return a / b;
};
std::cout << "10 / 2 = " << safeDivide(10.0, 2.0) << std::endl;
std::cout << "10 / 0 = " << safeDivide(10.0, 0.0) << std::endl;
// 2. Use appropriate data types
std::cout << "\n=== Choose Appropriate Data Types ===" << std::endl;
// Counting with int
int count = 0;
// Large integers with long long
long long bigNumber = 1234567890123456LL;
// Precise calculations with double
double precision = 0.123456789;
// Memory-sensitive scenarios with float
float memory_efficient = 3.14f;
std::cout << "count: " << count << std::endl;
std::cout << "bigNumber: " << bigNumber << std::endl;
std::cout << "precision: " << precision << std::endl;
std::cout << "memory_efficient: " << memory_efficient << std::endl;
// 3. Handle overflow
std::cout << "\n=== Overflow Checking ===" << std::endl;
auto safeMultiply = [](int a, int b) -> long long {
long long result = static_cast<long long>(a) * b;
if (result > std::numeric_limits<int>::max()) {
std::cout << "Warning: Integer overflow" << std::endl;
}
return result;
};
std::cout << "100000 * 50000 = " << safeMultiply(100000, 50000) << std::endl;
return 0;
}Summary
C++ provides powerful numeric processing capabilities, from basic operations to complex mathematical calculations:
Key Points
- Numeric types: Choose appropriate integer and floating point types
- Mathematical functions: Use the
<cmath>library for mathematical operations - Precision handling: Pay attention to floating point precision and comparison methods
- Type conversions: Master conversions between numeric types and strings
- Random numbers: Use modern C++ random number generators
Best Practices
- Use epsilon for floating point comparisons
- Choose appropriate data types to avoid overflow
- Perform input validation to prevent calculation errors
- Use standard library functions instead of implementing your own
- Pay attention to numeric calculation precision and performance
Good numeric processing skills are fundamental for scientific computing, graphics, game development, and other fields.