Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ How to correctly round a const float to unsigned int

Tags:

c++

So I have a const float that has a range from 0.0 to 1.0. What is the correct way to cast this to an unsigned int either by rounding or truncating?

Would this be acceptable?

const float f=0.5f;
unsigned int i=static_cast<unsigned int>(f);
like image 388
TriforceOfKirby Avatar asked Nov 19 '14 01:11

TriforceOfKirby


People also ask

How do you round a float to an int?

Since a float is bigger than int, you can convert a float to an int by simply down-casting it e.g. (int) 4.0f will give you integer 4. By the way, you must remember that typecasting just get rid of anything after the decimal point, they don't perform any rounding or flooring operation on the value.

How do I convert a float to an int in C?

The way to get the value is either the lib function int floor(float) or (for roundingup) int ceil(float).

How do I convert an int to unsigned?

To convert a signed integer to an unsigned integer, or to convert an unsigned integer to a signed integer you need only use a cast. For example: int a = 6; unsigned int b; int c; b = (unsigned int)a; c = (int)b; Actually in many cases you can dispense with the cast.

How do you round a float in CPP?

The round() function in C++ is used to round off the double, float or long double value passed to it as a parameter to the nearest integral value. The header file used to use the round() function in a c++ program is <cmath> or <tgmath>.


2 Answers

Yes, that's perfectly acceptable if you want to truncate, and if you don't care what happens with negative numbers or overflow.

If you want to round, call roundf first (or, if you want a different rounding rule than "half rounds away from zero", write your own code).

If you want to deal with negative numbers or overflow, you need to check before converting.

According to 5.2.9 in the standard, static_cast in this case is defined to give you the same value as unsigned int i(f). And I think most style guides would agree that the static_cast is preferred (as making casts explicit and noticeable is usually a good thing).

In more detail:

According to 4.9.1:

A prvalue of a floating point type can be converted to a prvalue of an integer type. The conversion trun- cates; that is, the fractional part is discarded. The behavior is undefined if the truncated value cannot be represented in the destination type.

I'm not sure exactly how the const-away works in C++14, but I believe it's not a qualification conversion, but part of the lvalue-to-rvalue conversion from 4.1.1:

A glvalue (3.10) of a non-function, non-array type T can be converted to a prvalue … If T is a non-class type, the type of the prvalue is the cv-unqualified version of T.

So, f has one lvalue-to-rvalue conversion from lvalue const float to rvalue float, then one floating-integral conversion from float to unsigned int, so by 4.0.1 it's a standard conversion, so by 5.2.9 it's valid as a static_cast.

like image 197
abarnert Avatar answered Oct 22 '22 18:10

abarnert


Just add one half to round:

unsigned int i = static_cast<unsigned int>(f + 0.5);

Or nothing to truncate - what you have is fine (assuming f >= 0)

unsigned int i = static_cast<unsigned int>(f);
like image 36
Barry Avatar answered Oct 22 '22 19:10

Barry