Reputation: 21
I want to round a float to maximum 4 decimals places. It mean 0.333333333 will be 0.3333, but 0.33 is still 0.33
Upvotes: 2
Views: 7696
Reputation: 41
_vsnprintf
I think the best solution for this is to just format the string. Because what if we don't need to output this number to the console, but save it in a std::string
variable or char[]
or something like that. This solution is flexible because it is the same if you output a number to the console and used the std::setprecision()
function, but also returning this number to char[]
.
So for this I used _vsnprintf
and va_list
. All it does is format the string as needed, in this case float value.
int FormatString(char* buf, size_t buf_size, const char* fmt, ...) {
va_list args;
va_start(args, fmt);
int w = _vsnprintf(buf, buf_size, fmt, args);
va_end(args);
if (buf == NULL)
return w;
if (w == -1 || w >= (int)buf_size)
w = (int)buf_size - 1;
buf[w] = 0;
return w;
}
int FormatStringFloat(char* buf, int buf_size, const void* p_data, const char* format) {
return FormatString(buf, buf_size, format, *(const float*)p_data);
}
#include "iostream"
#include "string"
#define ARRAY_SIZE(_ARR) ((int)(sizeof(_ARR) / sizeof(*(_ARR))))
int main() {
float value = 3.343535f;
char buf[64];
FormatStringFloat(buf, ARRAY_SIZE(buf), (void*)&value, "%.2f");
std::cout << std::string(buf) << std::endl;
return 0;
}
So by using "%.2f" we get from the 3.343535 => 3.34.
Upvotes: 0
Reputation: 37697
Assuming you need print rounded number, this is one of a proper solutions:
cout << setprecision(4) << x << '\n';
std::setprecision documentation.
Until more details are not provided it is impossible to provide a better answer.
Please note if you are planing to round number x
then print it, it will end with big headache, since some corner cases can produce much longer results then expected.
Upvotes: 0
Reputation: 131547
If you want to have your results rounded, with a fixed number of decimal digits, you're hinting that you don't really need the "floating" aspect of floating point numbers. Well, in this case, cast your value to a type which represents such numbers. Essentially, that would be a (run-time-variable) integer numerator and a compile-time-fixed denominator (which in your case would be 10,000).
There's an old question here on the site about doing fixed-point math:
What's the best way to do fixed-point math?
but I would suggest you consider the CNL library as something recent/popular. Also, several proposals have been made to add fixed-point types to the standard library. I don't know which one is the farthest advance, but have a look at this one: Fixed-Point Real Numbers by John McFarlane.
Back to your specific case: Fixed-point types can typically be constructed from floating-point ones. Just do that.
Upvotes: 2
Reputation: 131547
std::round()
functionThe C++ standard library offers functions for performing rounding. For float
s, it is:
float round ( float arg );
this will round arg
to the nearest integral value. Now, you want a different decimal resolution. So don't round your value, round your value times 10000, so your singles digit is now the former 0.0001 digit. Or more generally:
float my_round(
float x,
int num_decimal_precision_digits)
{
float power_of_10 = std::pow(10, num_decimal_precision_digits);
return std::round(x * power_of_10) / power_of_10;
}
Note that there may be accuracy issues, as floating-point computations and representations are only accurate to within a certain number of digits, and in my_round
we have at least four sources of such inaccuracy: The power-of-10 calculation, the multiplication, the devision and the actual rounding.
Upvotes: 4
Reputation: 620
Here is a solution, for example:
float ret = float(round(0.333333333 * 10000)) / 10000)
You can write it as a function. Maybe there would be a better way?
Upvotes: 0