Where is Round() in C++? [duplicate]
Asked Answered
B

4

38

Duplicate of: round() for float in C++


I'm using VS2008 and I've included math.h but I still can't find a round function. Does it exist?

I'm seeing a bunch of "add 0.5 and cast to int" solutions on google. Is that the best practice?

Barrios answered 16/2, 2009 at 19:1 Comment(3)
add 0.5 and cast to int won't work for negative numbers. The cast truncates (so it rounds -4.5 to -4). So attempting to round -5.0 will give you an output of-4 with this method. Replace the cast with ceil() and it should work. But yes, you have to implement your own, or find it in a 3rd party lib.Postlude
Er, assume I wrote floor() above, of course. To use ceil, you'd have to subtract 0.5Postlude
@jalf as I noted in my answer to the dup there are a lot of issues with rolling your own and today even if you are stuck with C++03 boost would be a better recommendation than attempting to roll your own.Footworn
S
64

You may use C++11's std::round().

If you are still stuck with older standards, you may use std::floor(), which always rounds to the lower number, and std::ceil(), which always rounds to the higher number.

To get the normal rounding behaviour, you would indeed use floor(i + 0.5).

This way will give you problems with negative numbers, a workaround for that problem is by using ceil() for negative numbers:

double round(double number)
{
    return number < 0.0 ? ceil(number - 0.5) : floor(number + 0.5);
}

Another, cleaner, but more resource-intensive, way is to make use of a stringstream and the input-/output-manipulators:

#include <iostream>
#include <sstream>

double round(double val, int precision)
{
    std::stringstream s;
    s << std::setprecision(precision) << std::setiosflags(std::ios_base::fixed) << val;
    s >> val;
    return val;
}

Only use the second approach if you are not low on resources and/or need to have control over the precision.

Seidule answered 16/2, 2009 at 19:7 Comment(11)
You think it's cleaner to convert to a string and back?Iams
Yes, using the +0.5-technique you will encounter problems with negative numbers and you also don't have control over the precision.Seidule
+0.5 should work fine as long as you use floor(). Anyway, then it becomes a question of correctness, and not which is cleaner.Postlude
what problems are there with negative numbers? if you don't need control precision then the stringstream solution is way slower for no reason. maybe a template-specialization would make sense here, if you really want to give precision control.Pastor
also, i should remind you that 0.5 is represented as an exact number.Pastor
Needed also to include <iomanip> (using MSVC 2012) to use the round function.Morbid
I prefer copysignf(floorf(fabs(x) + 0.5f), x) as it's branchless and the code that simulates the branch is literally bin-ops (abs -> &~0x80000000, copysign is a bit transfer, etc)Tactless
See my answer here, there is also trunc and boost available. Also see my link's to Pascal Cuoq's articles on why rolling your own can be very tricky.Footworn
@Pastor "what problems are there with negative numbers?" --> in the corner case of round(-0.0), this answer returns 0.0. -0.0 may be expected.Twopenny
Question starts with "I'm using VS2008..." and the answer starts with "You may use C++11's..." Don't you think there is some contradiction here? There is no std::round() function in VC2008.Gigantism
Note that the +0.5 trick is not completely right: blog.frama-c.com/index.php?post/2013/05/02/nearbyintf1Plait
D
14

Using floor(num + 0.5) won't work for negative numbers. In that case you need to use ceil(num - 0.5).

double roundToNearest(double num) {
    return (num > 0.0) ? floor(num + 0.5) : ceil(num - 0.5);
}
Doerr answered 16/2, 2009 at 19:15 Comment(0)
A
3

There actually isn't a round function in Microsoft math.h.
However you could use the static method Math::Round() instead.
(Depending on your project type.)

Alegar answered 16/2, 2009 at 19:7 Comment(1)
Visual studio now supports round see my comment here also see my answer for what I think is a full set of alternatives in a case where you can not use a more modern compiler.Footworn
R
0

I don't know if it's best practice or not but using the 0.5 technique with a floor() seems to be the way to go.

Repetition answered 16/2, 2009 at 19:8 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.