Skip to main content
GameDev.net gamedev.net
🔒 Locked

c++ decimal rounding

Started by fooman_69 Mar 31, 2005 at 4:54 PM 9 replies 17.6k views
Original Post
fooman_69
fooman_69
Can anyone point me to a place that shows me how to do this?
Evil Steve
Evil Steve
To round down, just cast to an int:
float f = 1234.5678; int n = (int)f;
To round to the nearest number, add 0.5 and cast:
float f = 1234.5678; int n = (int)(f+0.5f);
Telastyn
Telastyn
Or, the c library math.h provides:

double round(double);float  roundf(float);// as well asdouble ceil(double);float  ceilf(float);double floor(double);float floorf(float);


which do rounding, round up, and round down, respectively.
Polymorphic OOP
Polymorphic OOP
Quote:
Original post by Evil Steve
To round down, just cast to an int:
float f = 1234.5678; int n = (int)f;
To round to the nearest number, add 0.5 and cast:
float f = 1234.5678; int n = (int)(f+0.5f);

Casting to int does not round down, it truncates (which would round down for positive numbers and round up for negatives). As well, casting to an integer value and back is a costly operation. Use floor for rounding down.

Edit:

Quote:
Original post by Telastyn
Or, the c library math.h provides:


double round(double);
float roundf(float);<!--QUOTE-->


There's round in math? I don't think so...
fooman_69
fooman_69
how about if I want to round from 4 to 2 decimal places....
I knew about the math.h had the ceil and floor methods, but I'm not sure how to round without totally getting rid of all decimals.
Extrarius
Extrarius
Rounds Number to nearest Precision from Anchor
The return value is always representable as (Integer * Precision) + Anchor.

To round to 5 decimal places, use pow(10, -5) as the precision and 0 as Anchor.
To round to the nearest 3 from 1 (so possible values are 1, 4, 7, etc) use precision 3 and anchor 1.
double Round(double p_Number, double p_Precision, double p_Anchor = 0){   if(p_Number < p_Anchor)   {      return ceil((p_Number - p_Anchor) / p_Precision) * p_Precision + p_Anchor;   }   else   {      return floor((p_Number - p_Anchor) / p_Precision) * p_Precision + p_Anchor;   }}
"Walk not the trodden path, for it has borne it's burden." -John, Flying Monk
Polymorphic OOP
Polymorphic OOP
Quote:
Original post by fooman_69
how about if I want to round from 4 to 2 decimal places....
I knew about the math.h had the ceil and floor methods, but I'm not sure how to round without totally getting rid of all decimals.

You could multiply the number you are rounding by the base of the number system to the power of the number of places you wish to round off to. Then round that value, then divide back. Another option is you could add half of the accuracy, divide the starting value by the accuracy you need, round the result appropriately, then multiply that value by the accuracy you chose. Yet another option would be to take the starting value, add half of the accuracy and then subtract the result of an ::std::fmod (in cmath) of it by the accuracy you want. That's 3 different solutions.

Always keep in mind that you are dealing with floating point values so the exact rounded version of the value that you want may simply not be representable. Prefer using fixed point math if you absolutely must be exact.
Telastyn
Telastyn
Quote:
Original post by Polymorphic OOP
There's round in math? I don't think so...


ROUND(3)                NetBSD Library Functions Manual               ROUND(3)NAME     round, roundf - round to nearest integral valueLIBRARY     Math Library (libm, -lm)SYNOPSIS     #include <math.h>     double     round(double x);     float     roundf(float x);DESCRIPTION     The round() and roundf() functions return the nearest integral value to     x; if x lies halfway between two integral values, then these functions     return the integral value with the larger absolute value (i.e., they     round away from zero).SEE ALSO     ceil(3), floor(3), ieee(3), math(3), rint(3)STANDARDS     The round() function conforms to ISO/IEC 9899:1999 (``ISO C99'').


Relatively recent addition, but it's there.
Polymorphic OOP
Polymorphic OOP
Quote:
Original post by Telastyn
Quote:
Original post by Polymorphic OOP
There's round in math? I don't think so...


*** Source Snippet Removed ***

Relatively recent addition, but it's there.

Are you sure it's standard? I don't believe so. Comeau doesn't recognize it in C99 mode though does in C90. Also, I don't see it mentioned in the C++ standard and comeau does not recognize it in C++ mode either.

Edit: I guess it is standard in C99 and comeau just doesn't recognize it for some reason.
silvermace
silvermace
i avoid all of that C99/C90 compatability bs by using a very basic template function:

#include <iterator>#include <algorithm>#include <string>#include <vector>#include <iostream>/* * Templated round function * * @author: Danushka "silvermace" Abeysuriya * @template param: T, data type and return type * @template param: Ndp, the number of decimal places to round to * @param: val, the value to be rounded * @returns: rounded val to Ndp decimal places of type T */template< typename T, const int Ndp >T round( const T val ){	T raised  = pow( 10, (double)( abs(Ndp) ) );	T temp 	 = val * raised;	T rounded = static_cast<T>( floor( temp ) );	if( temp - rounded >= (T)0.5 ) {		rounded = static_cast<T>( ceil( temp ) );	}	return static_cast<T>(rounded / raised);}/* * unit tester function */int main(){	std::vector<float> test;	test.push_back( round<float, 1>( 3.32645f ) );	test.push_back( round<float, 2>( 3.32645f ) );	test.push_back( round<float, 3>( 3.32645f ) );	test.push_back( round<float, 4>( 3.32645f ) );	test.push_back( round<float, 5>( 3.32645f ) );	std::copy( test.begin(), test.end(),			   std::ostream_iterator< float >(std::cout, "\n") );	return 0;}
produces output:
3.33.333.3263.32653.32645

slow, maybe.. but it works damnit. (and if this is your bottleneck, you shouldn't be programming anyway, go do a bachelour of planning or something that only requires a pulse.)

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.