How to convert a float to an int in modern C++

12,362

Solution 1

As Josh pointed out in the comments, + 0.5 is not very reliable. For extra security you could combine a static_cast with std::round like so:

int int_value = static_cast<int>(std::round(float_value));

For the casting part, see this excellent post for an explanation.

Solution 2

try:

int int_value = static_cast<int>(float_value + 0.5);

FYI: different casts in C++ gave a very good explanation about those 4 casts introduced in C++.

Solution 3

You could also consider

int int_value = boost::lexical_cast<int>(float_value);

lexical_cast has the benefit of working for all primitive types, and stl strings etc. It also means you don't have to do the (float_value + 0.5) stuff.

Share:
12,362
Offirmo
Author by

Offirmo

~12 years of experience in web development in javascript / html / css, big enterprise apps in C++ and embedded network devices in C. Mostly interested in web app development, javascript, Python, C++... SOreadytohelp !

Updated on June 20, 2022

Comments

  • Offirmo
    Offirmo almost 2 years

    As strange as it may seems, I can't find how to cleanly convert a float to an int.

    This technique

    int int_value = (int)(float_value + 0.5);
    

    triggers a

    warning: use of old-style cast
    

    in gcc.

    So, what is the modern-style, simple way to convert a float to an int ? (I accept the loss of precision of course)

  • Josh Kelley
    Josh Kelley almost 11 years
    + 0.5 is a surprisingly unreliable way to round, due to floating point math issues. See blog.frama-c.com/index.php?post/2013/05/02/nearbyintf1.
  • Ulrich Eckhardt
    Ulrich Eckhardt almost 11 years
    This won't work if the intermediate string contains a decimal point though, and that's likely for a float. Or, if the float is huge. Further, for rounding of negative values, you want to subtract 0.5, so rounding isn't that easy anyway.
  • James Kanze
    James Kanze almost 11 years
    The static_cast does absolutely nothing here; once you've done std::round, you can just forget it (and get undefined behavior if the flow doesn't fit), or you can assign the results to a float, and check against std::numeric_limits<int>::max() and std::numeric_limits<int>::min before doing the assignment. (The lexical_cast is a very bad idea, since it doesn't work.)
  • Victor Sand
    Victor Sand almost 11 years
    @JamesKanze: Couldn't omitting the cast generate warnings about precision loss?
  • James Kanze
    James Kanze almost 11 years
    @VictorSand A compiler can warn about anything it feels like, including in the presence of a cast. In practice, though... an explicit cast is the traditional way of telling the compiler you know what you're doing, and that this isn't an oversight, so yes, I would expect the cast to have an impact on warnings.