Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is the return value type of std::round not an integer?

I had/have some confusion regarding rounding a float/double variable to the nearest integer. While googling, I came across this cppreference page for rounding. On that page, it says:

float       round ( float arg );         // (1)
float       roundf( float arg );         // (2)
double      round ( double arg );        // (3)
long double round ( long double arg );   // (4)
double      round ( IntegralType arg );  // (5)

Here, I don't understand why is the return value type float, double, or long double? For example, if I have a variable float x and 2.5 <= x < 3.5 then its rounded value is 3. That can be represented using just an int, right? So, why is the return value type of std::round not an int (or long it for long double)?


On that page, it also says:

1-5) Computes the nearest integer value to arg (in floating-point format), rounding halfway cases away from zero, regardless of the current rounding mode.

So, what does exactly "integer value to arg (in floating-point format)" mean?


To understand this std::round, I did one small experiment:

int main(int argc, char const *argv[]) {
    float var               = 3.14;
    int   rounded_var_int   = std::round(var);
    float rounded_var_float = std::round(var);

    std::cout << rounded_var_int << ", " << rounded_var_float << std::endl;  // 3, 3
    
    return 0;
}

However, this made me even more confused because everything ran just fine.

So, the last question:
In the above code, int rounded_var_int = std::round(var) is just fine or do I need to explicitly cast it to int e.g. int rounded_var_int = static_cast<int>(std::round(var)) to avoid any potential bug(s)?

like image 722
Milan Avatar asked Oct 23 '25 03:10

Milan


1 Answers

Why is the return value type of std::round not an integer?

Because the representable range of floating point types generally exceed the range of fundamental integer types and thus those integer types cannot represent all potential return values.

Besides finite rounded values that exceed the range of integer types, other problematic values are infinities, not-a-number values, negative zero which are returned without change.

rounded value is 3. That can be represented using just an int, right?

This value can be represented using int. But being able to represent one, or some of the values isn't sufficient. The return type should be able to represent all rounded values. And that isn't generally achievable with int.

In the above code, int rounded_var_int = std::round(var) is just fine or do I need to explicitly cast it to int e.g. int rounded_var_int = static_cast<int>(std::round(var)) to avoid any potential bug(s)?

Floating point types are implicitly convertible to integer types. The result of the implicit conversion is the same as the result of the static cast.

It is a narrowing conversion. Neither implicit nor explicit conversion is safe in the sense that if the floating point value is outside of representable range, then the behaviour of the program is undefined. Both conversions are safe in the sense that if the value is representable, then the value will remain unchanged by the conversion.

like image 178
eerorika Avatar answered Oct 24 '25 20:10

eerorika



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!