# Rounding Floating Point Values

This topic is 5227 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

I need a function that mimicks excel's ROUNDUP function. Basically the ROUNDUP function is described like this: It rounds a value away from zero with two given parameters. Parameter 1 is the number to round, and parameter 2 is the digit to round to. If the rounding digit is 0 it rounds to the nearest whole number, and negative numbers round to the left of the decimal point. For example: ROUNDUP(5.5, 0) = 6 ROUNDUP(-5.5, 0) = -6 ROUNDUP(55, -1) = 60 ROUNDUP(3.14159, 1) = 3.1 Is there any C function that supplies this sort of functionality? I've been writing my own but it is very tedious and somewhat exausting. Thanks

##### Share on other sites
You can use ceil to round up and use some dividing/multiplying by 10 to round to decimal places. You'd still have to write your own, but it'll probably be easier than whatever you're writing now (unless that's actually what you're doing).

For instance, float x = ceil(55f / 10f) * 10f; would round 55 to 60.

That better, hplus0603? [wink]

##### Share on other sites
Be careful to cast to double -- the literal "55 / 10" actually evaluates to 5, not 5.5. The ceil() of 5 is 5.

##### Share on other sites
I was bored and was up for a bit of a challenge. Five minutes later this seems to do what you intend it to.. tell me if it doesn't work as you expected.

float roundup(float Num, int Places){ float mod = pow(10,places); if (Places > 0)   Num *= mod; if (Places < 0)  Num /= mod; if (Num > 0)  Num += 0.5f; else  Num -= 0.5f; Num = (float) int(Num); if (Places > 0)  Num /= mod; if (Places < 0)  Num *= mod;  return Num;}

EDIT: Did a quick fix on the code.. silly me for not noticing that.

[Edited by - falkone on August 27, 2004 11:48:01 AM]

##### Share on other sites
Your code won't work. Besides the inefficient float/int conversion, test your code when Places is 2. It won't work. This will work in all cases:
float RoundUp ( float Num, float Places ){    float Shift = powf(10, Places);    Num *= Shift;    if( Num < 0 )        Num = -ceilf(-Num);    else        Num = ceilf(Num);    Num /= Shift;    return Num;}

##### Share on other sites
Yah bro if you want to do the base 10 deal it needs to be exponential. I wrote up something that looks like this and it does what I want:

[SOURCE]float roundf(const float fValue, const int iDigit) {        if(iDigit==0) {                if((float)(int)fValue==fValue) {                        return fValue;                }                float fRetVal = (float)(int)fValue;                if(fValue>0.0) {                        fRetVal+=1.0f;                }                 else if(fValue<0.0) {                        fRetVal-=1.0f;                }                return fRetVal;        }        else if(iDigit < 0) {				float fTemp = (float)pow(10.0, (double)(-1*iDigit));                float fScaledValue = fValue / fTemp;				if((float)(int)fScaledValue*fTemp==fValue) {					return fValue;				}				else {					if(fScaledValue<0) {						fScaledValue = (float)(int)fScaledValue;						fScaledValue-=1.0f;						fScaledValue*=fTemp;					}					else {						fScaledValue = (float)(int)fScaledValue;						fScaledValue+=1.0f;						fScaledValue*=fTemp;					}					return fScaledValue;				}        }		else {				float fTemp = (float)pow(10.0, (double)(iDigit));                float fScaledValue = fValue * fTemp;				if((float)(int)fScaledValue/fTemp==fValue) {					return fValue;				}				else {					if(fScaledValue<0) {						fScaledValue = (float)(int)fScaledValue;						fScaledValue-=1.0f;						fScaledValue/=fTemp;					}					else {						fScaledValue = (float)(int)fScaledValue;						fScaledValue+=1.0f;						fScaledValue/=fTemp;					}					return fScaledValue;				}		}}[/SOURCE]

The only catch is that sometimes I get added crap on the end (I blame the fpu) and it does a really poor job of doing floats past the 4th digit to the right of the decimal. Can anybody verify that this works? What concerns me is when I pass it:
-911.12345 with 1 as the digit I get -911.200012 instead of -911.200012, and I think this problem manifests itself more strongly when I do digits like 5 and 4. Thanks.

##### Share on other sites
That code is much slower and more complicated than it needs to be. You'll find mine works in all cases. I did a test run with your number and these are the results:

RoundUp(-911.12345f, 1) prints "-911.200000"
RoundUp(-911.12345f, 4) prints "-911.123500"
RoundUp(-911.12345f, -2) prints "-1000.000022"

That 22 at the end is a result of 32-bit floating-point imprecision.

##### Share on other sites
Quote:
 Original post by CGameProgrammertest your code when Places is 2.

Oopsies, I wasn't even thinking about that.. silly me

##### Share on other sites
Ok your code and my code are effected by the same inaccuracy (which really sucks). I tried converting your code to using doubles and then casting to a float and the same inaccuracy exists. But yah, my implementation was way more complicated then it needed to be. Thanks for your help.

##### Share on other sites
Quote:
 Original post by 31337I tried converting your code to using doubles and then casting to a float and the same inaccuracy exists.

Yeah, even directly assigning a number to a float can still show precision errors. In Visual C++, if you say "float var = 0.1" it'll generate a warning for converting a double to a float. This is because 0.1 cannot be stored exactly in floating-point format, but a double would at least be more accurate than a float. It's like storing 1/7 in decimal format, which is 0.1428571428... infinite digits. You can't represent the exact number.

1. 1
2. 2
Rutin
19
3. 3
khawk
18
4. 4
5. 5
A4L
11

• 12
• 16
• 26
• 10
• 44
• ### Forum Statistics

• Total Topics
633768
• Total Posts
3013743
×