hey guys, as well all know, C rounds downwards, anyway, i'm trying to write a function that would make it round upwards, and got something like this:

int
round_up(float x)
{
	int y = 100*x;
	double z = 100*x-y;
	if(z>0)
		y = (x+0.01)*100;
	else
		y = x*100;
	return y;	
}

but the thing is if i have a test case with x = 0.80, the value of z, which is

100*0.80 - 80
is not actually equal to 0, i printed out the value and it gave me something like 0.0000001. I know this is because of the limitations of the machine being 32 bits, but is there anyway to around this? I was thinking of making the if statement into

if(z > 0.00001)

or something similar, but thats really a last resort

thanks.

Since your examples are ambiguous, you need to be a little more explicit.

Starting at 2.000, what values gets rounded up to 3.000? 2.001? 2.100? 2.5?

If it's as low as anything > 2.000, simply add 1.0 and truncate.

You have not fully taken on board the nature of floats (and doubles). it has nothing to do with the machine being 32 bits, it is the nature of how floats hold there values that they are approximations (normally good ones) that is a float is rarely 2.5 or 3.0 it will be 2.499999 or 3.00001 with the possible exception of a float variable immediately following initialisation.

You are multiplying by 100 and then trying to test the remaining decimal places to see if they are 0 and if they are not 0 rounding up. However because of this aprroximate behaviour except for a variable immediately following initialisation so any value that has been calculated you have to assume that the digits following the ones you are interested in are always non-zero.

Even for the simple multiplication * 100. A float may be able to hold 2.500 exactly and it may be able to hold 250.00 exactly but 2.500 * 100.0 could result in 249.99.

So under the assumption that the trailing digits of a floating point variable following some calculations are never 0 and the strict definition of rounding up you will always be rounding up.

In that case you can save yourself the hassle of the calculation, * 100 truncate and + 1.

That is probably not want you want to here but that is the nature of floats.

Your only other option is what you have suggested, choose a tolerance that suits you and treat everything below that tolerance as 0. You do not need an if statement you can do it with simple arithmatic just add the value below which you are willing to treat everything as 0. For instance normal rounding ( everything >= 0.5 up and eveything else down) on a x 100 value look something like this

int output;
float input = <some value>;

output = (input + 0.005) * 100;

// Alternitively
output = input * 100 + 0.5;

The addition handles the rounding making the value large enough that upon truncation to an int if required it is rounded up.

Choose the value you add to adjust where the round up/round down point is.

commented: very nice :) +27

dont use float

do use double

if you want to round up to the next single unit (one's place), then just add 1.0 and recast it as an int to drop the fractional parts.

if you want to round up at a certain decimal place, then first multiply by a power of 10 to the number of decimal places you want to round (e.g., 4 decimal places = 10^4 = 10000), then add 1.0 and recast as an int to drop the fractional parts, then divide by that same power of 10.

example, to round a number to the highest 1/100'ths place:

double x = 123.1234;

printf("original value is %f\n",x);

               // x =   123.1234
x = x * 100;   // x = 12312.3400
x = (int)x + 1 // x = 12313.0000
x = x / 100    // x =   123.1300

printf("rounded value is  %f\n",x);

.

use something like this:

#include <stdio.h>
#include <math.h>
#define sign(x) ((x>0.0)-(x<0.0))

double roundup(double val) {
	double fracp, intp;
	fracp = modf(val , &intp);
	return intp+((fabs(fracp) >= 0.5)? sign(fracp):0);
}

int main ()
{
	printf("%lf rounded to %lf\n",2.15,roundup(2.15));
	printf("%lf rounded to %lf\n",2.55,roundup(2.55));
	printf("%lf rounded to %lf\n",-2.15,roundup(-2.15));
	printf("%lf rounded to %lf\n",-2.55,roundup(-2.55));
	return 0;
}
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.