Type Conversions

Values often need converting: an int to a double for division, text from the user into a number, a number into text. C++ does some conversions implicitly, provides named casts for explicit ones, and has library functions for converting between strings and numbers.

Implicit conversions

In mixed arithmetic, the narrower type is converted to the wider one. Assigning to a narrower type converts too — silently losing data:

C++
#include <iostream>

int main() {
    int items = 7;
    double weight = 0.5;
    std::cout << items * weight << '\n';     // int converted to double

    double precise = 9.99;
    int truncated = precise;                 // fraction dropped
    std::cout << truncated << '\n';
}
Output
3.5
9

Brace initialisation refuses such narrowing (lesson 4), and -Wconversion warns about it.

static_cast

To convert explicitly, use static_cast<Type>(value). It's easy to search for and says clearly that the conversion is intentional:

C++
#include <iostream>

int main() {
    int total = 17, count = 4;
    std::cout << total / count << '\n';                          // 4: integer division
    std::cout << static_cast<double>(total) / count << '\n';     // 4.25

    double price = 19.99;
    int whole = static_cast<int>(price);
    char letter = static_cast<char>(65);
    std::cout << whole << ' ' << letter << '\n';
}
Output
4
4.25
19 A

C++ has three other named casts for special situations — const_cast (removing const), reinterpret_cast (reinterpreting raw bits) and dynamic_cast (checked down-casts in class hierarchies, lesson 37). C-style casts like (int) x still work but can silently do any of these, so prefer the named forms.

Rounding

Casting to an integer truncates toward zero. For rounding, use <cmath>:

C++
#include <cmath>
#include <iostream>

int main() {
    for (double v : {2.5, 2.4, -2.5, -2.6}) {
        std::cout << v << ": cast " << static_cast<int>(v) << ", round " << std::round(v)
                  << ", floor " << std::floor(v) << ", ceil " << std::ceil(v) << '\n';
    }
}
Output
2.5: cast 2, round 3, floor 2, ceil 3
2.4: cast 2, round 2, floor 2, ceil 3
-2.5: cast -2, round -3, floor -3, ceil -2
-2.6: cast -2, round -3, floor -3, ceil -2

Strings to numbers

std::stoi, std::stol and std::stod parse a string. They throw an exception if no number can be read, and report how many characters they used:

C++
#include <iostream>
#include <stdexcept>
#include <string>

int main() {
    for (std::string text : {"42", "3.75", "12abc", "abc"}) {
        try {
            std::size_t used = 0;
            int n = std::stoi(text, &used);
            std::cout << text << " -> " << n;
            if (used < text.size()) std::cout << " (ignored \"" << text.substr(used) << "\")";
            std::cout << '\n';
        } catch (const std::invalid_argument&) {
            std::cout << text << " -> not a number\n";
        }
    }
    std::cout << std::stod("3.75") * 2 << '\n';
}
Output
42 -> 42
3.75 -> 3 (ignored ".75")
12abc -> 12 (ignored "abc")
abc -> not a number
7.5

Exceptions are covered in lesson 42. For the fastest parsing with no exceptions, <charconv> provides std::from_chars:

C++
#include <charconv>
#include <iostream>
#include <string_view>

int main() {
    std::string_view text = "2048 bytes";
    int value = 0;
    auto [ptr, error] = std::from_chars(text.data(), text.data() + text.size(), value);
    if (error == std::errc{}) {
        std::cout << "parsed " << value << ", rest: \"" << ptr << "\"\n";
    }
}
Output
parsed 2048, rest: " bytes"

Numbers to strings

C++
#include <format>
#include <iostream>
#include <string>

int main() {
    std::string a = std::to_string(42);
    std::string b = std::to_string(3.5);              // always 6 decimals
    std::string c = std::format("{:.2f}", 3.14159);   // full control (C++20)
    std::cout << a + " | " + b + " | " + c << '\n';
}
Output
42 | 3.500000 | 3.14

std::format (lesson 45) is the flexible choice; std::to_string is the quick one.

Characters and digits

C++
#include <iostream>

int main() {
    char digit = '7';
    int value = digit - '0';                  // '0'..'9' are consecutive codes
    char next = static_cast<char>('a' + 1);
    std::cout << value * 2 << ' ' << next << ' ' << static_cast<int>('A') << '\n';
}
Output
14 b 65

Try it yourself

Read lines of input, convert each to a number if possible, and print the sum of the valid ones.

Try it yourself · main.cpp
Edit the code, copy it into main.cpp, then compile and run it with c++ -std=c++20 -Wall main.cpp -o main && ./main. How to set up a C++ compiler
Input
12.5
seven
30
1e2
Output
skipping "seven"
sum = 142.5