Rounding Based On Math - Not Just Up Or Down

SkippyThorson

macrumors 68000
Original poster
Jul 22, 2007
1,513
498
Utica, NY
So the next task in my travels is rounding. I don't mean to come on here each week and pester those that have better things to do, but I hope it is proper for me to ask so frequently. (If not, tell me so.:eek:)

The following that I have works. It does just what I need - Round to two decimal places, up or down, based on simple math. However my instructor insists we must have another snippet of her code in the program. Why? I'm not too sure. I guess I'm looking for a how-to-and-why sort of thing.

#include <stdio.h>
#include <math.h>
int main(void)

{
double x;
int rounded_x;

printf ("Welcome.\n");
printf("Enter a positive number: \n");
scanf("%lf", &x);

rounded_x = (int) (x + .5);

// double scale_factor;
// {
// double scale_factor;
// scale_factor = pow(10,rounded_x);
// return (x * scale_factor);
// }

printf("Rounded number is: %.2lf \n", x);

return 0;
}
The /*double scale_factor*/ portion is what I don't get. Without it, it already does what I need. All in all, I don't know what her little portion does or why I'd need it. Again, thank you greatly in advance to all.
 

Catfish_Man

macrumors 68030
Sep 13, 2001
2,579
1
Portland, OR
That's... rather bizarre. Why the double declaration of scale_factor? Why the unnecessary nested scope? What on earth is scaling it doing in a rounding function?


Are you sure you're putting that in the right place, and it's not intended to be a separate function?
 

chown33

Moderator
Staff member
Aug 9, 2009
8,356
4,330
Gourd City
Your code is displaying a rounded number, but it's not displaying the rounded_x you calculated. Walk through the code and you'll see it.

It's displaying a rounded number because the format specifier for printf is specifying two decimal places, and printf does rounding.

If I understand your assignment correctly, you're supposed to calculate a number rounded to 2 places. Which is not the same thing as displaying a number rounded to 2 places. You might discuss this with your instructor, because I may be miunderstanding the assignment.


Also, read the man pages for rint and round.
 

lloyddean

macrumors 65816
May 10, 2009
1,001
16
Des Moines, WA
What is the assignment exactly? Not paraphrased, because I don't think you understand it properly, or haven't explained to us properly. Either way this makes it difficult to render assistance with whats been given here.
 

SkippyThorson

macrumors 68000
Original poster
Jul 22, 2007
1,513
498
Utica, NY
Apologies - the assignment itself is to write a program that takes a positive number with a decimal and round it to two decimal places. There are two segments of code that must be included, and are as follows;

double x;
int rounded_x;
/*code to give value to x*/
rounded_x = (int) (x + 0.5);
and

/*x and n are defined, math.h is included*/
double scale(double,x int n)
{
double scale_factor; /*local variable*/
scale_factor = pow(10,n);
return (x * scale_factor);
I wasn't aware that printf would round. Our current instructor replaced the instructor we should have had. I'm not getting a whole lot out of it.

Are you sure you're putting that in the right place, and it's not intended to be a separate function?
It is intended to be a separate function, however I just stuck it in that spot so I didn't forget it once I wrote it down. It is not intended to be in that particular spot. :eek:
 

lee1210

macrumors 68040
Jan 10, 2005
3,180
1
Dallas, TX
It is unfortunate that your instructor is not working out how you had hoped. This assignment, however, is extremely simple. You need to think this out before you start coding. You want to round to two decimal places. There is some code there that will round to the nearest whole number. So what would you do to the number:
125.3463

If the only operations you can perform on this number are to shift the decimal places, and round to the nearest whole number, how might you combine these steps to get a number rounded to two decimal places? I'll give you a hint, there are three steps. Two of them are using a function you were given (it is a function that needs to be outside of main, not a block inside of main). It should be:
Code:
double scale(double x, int n) {
  double scale_factor; /*local variable*/
  scale_factor = pow(10,n);
  return (x * scale_factor);
}
So work it out... note that the number of positions that scale will shift a value doesn't have to be positive.

Good luck.

-Lee
 

SkippyThorson

macrumors 68000
Original poster
Jul 22, 2007
1,513
498
Utica, NY
Well, I've been working on this for about two hours with a buddy of mine, and it comes back error-free again. However, it looks like it's doing the same thing as before; what someone else said, displaying and not calculating. Perhaps I'm still on the wrong road?

#include <stdio.h>
#include <math.h>
int main(void)

{
//variables
double x;
int rounded_x;
double scale(double, int);

//input
printf ("Welcome.\n");
printf("Enter a positive number: \n");
scanf("%lf", &x);

//equation
rounded_x = (int) (x + .005);
//call to scale
scale(x, rounded_x);

//output
printf("Rounded number is: %.2lf \n", x);

return 0;
}

//function outside of main
double scale(double x, int n)
{
double scale_factor;
scale_factor = pow(10,n);
return (x * scale_factor);
}
Lee (and all) I'm sorry that I'm n00b*10 at this. Just wanted to note that I truly appreciate the hints, instead of the direct answer.
 

chown33

Moderator
Staff member
Aug 9, 2009
8,356
4,330
Gourd City
Well, I've been working on this for about two hours with a buddy of mine, and it comes back error-free again. However, it looks like it's doing the same thing as before; what someone else said, displaying and not calculating. Perhaps I'm still on the wrong road?
I think you need to walk through this manually before trying to write code for it. The procedure or process is crucial (it's technical term is algorithm). Without it, you're just throwing code around hoping something will work.

You play the computer, and your buddy plays the user. You say "Welcome. Enter a positive number." and he writes down "4.347" and hands it to you. Now using what lee1210 wrote earlier, you have to walk through the individual steps to produce the rounded number. You must describe each step out loud to your buddy. You are not allowed to say "Round to 2 digits".

This will require that you think through the details of mathematical processes you may not even realize you perform in your head. That's what programming is: details of processes.
 

lee1210

macrumors 68040
Jan 10, 2005
3,180
1
Dallas, TX
I saw Xcode for the first time 3 weeks ago - please don't condescend. Instead, explain; are you referring to the return 0? Not sure I understand.
lloyddean wasn't being condescending. He's asking you to explain why the return value from scale isn't being assigned to anything. This is perfectly valid. So what variable might you assign it's return value to?

Also, as I said earlier, you need to call scale first. You are not using the code you were told to use, you have scaled the .5 to .005. This is breaking the rules. I wouldn't turn it in without the exact code they said to use.

You're also not passing the right thing to scale. The second parameter is how many places you'd like to shift. This should be 2 and something that looks a lot like 2 for the two calls you'll make to scale.

-Lee

-Lee
 

SkippyThorson

macrumors 68000
Original poster
Jul 22, 2007
1,513
498
Utica, NY
lloyddean wasn't being condescending. He's asking you to explain why the return value from scale isn't being assigned to anything. This is perfectly valid. So what variable might you assign it's return value to?
Well, it makes sense that the return value from scale, using x, should be assigned to rounded_x.

Also, as I said earlier, you need to call scale first. You are not using the code you were told to use, you have scaled the .5 to .005. This is breaking the rules. I wouldn't turn it in without the exact code they said to use.
My thinking behind the .005 was if it was 2 decimal points, it would make sense that it would be scaled to .005 instead. You're right, though. Better safe.

You're also not passing the right thing to scale. The second parameter is how many places you'd like to shift. This should be 2 and something that looks a lot like 2 for the two calls you'll make to scale.
The calls to scale are literally values, and not the values of int / double. Now that's where not even the book was clear on it. It would make sense that the two calls are 2 and -2. Which, duh, falls in line with everything you said.:rolleyes:

Maybe this isn't my calling? Everyone has to start somewhere, but maybe I should have started 10 years ago? I just know that I can take the easy route, or challenge myself, and I know this is something that I'm definitely willing to learn. Which is more than I can say for a lot of people I know.

lloyddean - I am sorry. -- Inflection needs to be developed for the internet. I took that the wrong way.
 

Detrius

macrumors 68000
Sep 10, 2008
1,621
19
Asheville, NC
Here's a little tip. Since you're worried that printf is doing the rounding for you, you should have printf show you more digits than you're trying to round to. That way, if the rounding fails, you'll see it.

change this:
Code:
printf("Rounded number is: %.2lf \n", x);
to:
Code:
printf("Rounded number is: %.3lf \n", x);
It will show three digits after the decimal. If this digit isn't zero, you didn't round.
 

SkippyThorson

macrumors 68000
Original poster
Jul 22, 2007
1,513
498
Utica, NY
That's what emoticons were supposed to provide. But my experience with them is that even their intent is colored by the "mood" of the individual seeing them.
I've had a lot of experience with :eek: lately, but that's about it. Thank you for the help too. It stuck with me.

I'll keep that 2lf / 3lf idea in mind too -- however, if printf does rounding, wouldn't it instead just trunkate after 3 numbers instead, doing the same thing?
 

Detrius

macrumors 68000
Sep 10, 2008
1,621
19
Asheville, NC
I'll keep that 2lf / 3lf idea in mind too -- however, if printf does rounding, wouldn't it instead just trunkate after 3 numbers instead, doing the same thing?
Yes, it will, but if your code is supposed to round at two decimal places, it would help if printf were showing more than two decimal places so that you can see that it actually worked.

e.g.

input: 3.14159

printf at 2 decimal places: 3.14
proper rounding to 2 decimal places: 3.14
improper rounding to 2 decimal places with printf showing 2: 3.14

printf at 3 decimal places: 3.141 -- maybe 3.142 if it rounds
proper rounding to 2 decimal places with printf showing 3: 3.140
improper rounding to 2 with printf showing 3: 3.141 -- maybe 3.142 if printf rounds for you


See? If printf is only showing two decimal places, you'll never know whether you did it correctly or not from the printf output.
 

SkippyThorson

macrumors 68000
Original poster
Jul 22, 2007
1,513
498
Utica, NY
Naturally, this week I had no problem, but she wanted me to re-work this one. Her words were "If you print it out with 4 after the decimal,it simply prints the same number." Ugh. She also said I should spruce up my documentation. Here's what I wound up with:

#include <stdio.h>
#include <math.h>
int main(void)

{
//variables
double x;
int rounded_x;
double scale(double, int);
//input
printf ("Welcome.\n");
printf("Enter a positive number: \n");
//the number is set to x
scanf("%lf", &x);
//call to scale, for rounded_x
rounded_x = scale(2, -2);
//equation for the rounded number
rounded_x = (int) (x + .5);
//output
printf("Rounded number is: %.2lf \n", x);
//end
return 0;
}

//function outside of main
//double x and int n represent x and rounded_x
//scale_factor is a power of 10
double scale(double x, int n)
{
double scale_factor;
scale_factor = pow(10,n);
return (x * scale_factor);
}
 

lloyddean

macrumors 65816
May 10, 2009
1,001
16
Des Moines, WA
Out of curiosity - do you have the exact wording of the assignment that you'd be willing to post. I, for one, don't get enough from what you've posted to be of much help.
 

lloyddean

macrumors 65816
May 10, 2009
1,001
16
Des Moines, WA
Code:
int main(void)
{
	double x;
	int rounded_x;
	double scale(double, int);

	printf ("Welcome.\n");
	printf("Enter a positive number: \n");

	scanf("%lf", &x);

	rounded_x = scale(2, -2);
	rounded_x = (int) (x + .5);

	printf("Rounded number is: %.2lf \n", x);

	return 0;
}
I see that scale is called:

Code:
	rounded_x = scale(2, -2);
Then the next line you overwrite 'rounded_x' so you might as well have not called 'scale' at all like this:

Code:
int main(void)
{
	double x;
	int rounded_x;
	double scale(double, int);

	printf ("Welcome.\n");
	printf("Enter a positive number: \n");

	scanf("%lf", &x);

	rounded_x = (int) (x + .5);

	printf("Rounded number is: %.2lf \n", x);

	return 0;
}
Then you output a value using 'printf' that ocmpletely ignors your 'rounded_x' calculated in the proceeding line leaving:

Code:
int main(void)
{
	double x;
	int rounded_x;
	double scale(double, int);

	printf ("Welcome.\n");
	printf("Enter a positive number: \n");

	scanf("%lf", &x);

	printf("Rounded number is: %.2lf \n", x);

	return 0;
}
Now variable 'rounded_x' is not used and 'scale' is no longer called leaving you with:

Code:
int main(void)
{
	double x;

	printf ("Welcome.\n");
	printf("Enter a positive number: \n");

	scanf("%lf", &x);

	printf("Rounded number is: %.2lf \n", x);

	return 0;
}
Which is right back where you started the whole query with. Effectively nothing accomplished!
 

SkippyThorson

macrumors 68000
Original poster
Jul 22, 2007
1,513
498
Utica, NY
Out of curiosity - do you have the exact wording of the assignment that you'd be willing to post. I, for one, don't get enough from what you've posted to be of much help.
What I put above is all I have - "Write a program that takes a positive number with a fractional part and rounds it to two decimal places." The following code must also be included.

double x;
int rounded_x;
/*code to give value to x*/
rounded_x = (int) (x + 0.5);
and

/*x and n are defined, math.h is included*/
double scale(double,x int n)
{
double scale_factor; /*local variable*/
scale_factor = pow(10,n);
return (x * scale_factor);
Which Lee wrote as:

double scale(double x, int n) {
double scale_factor; /*local variable*/
scale_factor = pow(10,n);
return (x * scale_factor);
}
That's all I have that she gave us. Those instructions and those segments of code.
 

chown33

Moderator
Staff member
Aug 9, 2009
8,356
4,330
Gourd City
What I put above is all I have - "Write a program that takes a positive number with a fractional part and rounds it to two decimal places." The following code must also be included.
Code:
double x;
int rounded_x;
/*code to give value to x*/
rounded_x = (int) (x + 0.5);
Break it down.

Step 1. Decide how to represent values.

Given that rounded_x is an int, which can only hold integers, how would you represent a number with exactly two decimal places, which is stored in rounded_x?

There is a fairly simple solution for this part of the overall problem. Enough suggestions have already been provided in previous posts that you should be able to figure this out. Without it, you will not be able to solve the overall problem.

Step 2. To be determined after Step 1 is solved.

Step 3. Profit!
 

notjustjay

macrumors 603
Sep 19, 2003
6,040
111
Canada, eh?
Maybe this isn't my calling? Everyone has to start somewhere, but maybe I should have started 10 years ago?
The problem with the way they teach programming these days is that they focus so much on code syntax and keywords, and in modern languages, complex concepts like object instantiation and deletion, and even GUI wrappers, without giving enough attention to teaching you to "think like a computer". Different people learn this skill at different speeds, and the programming classes tend to be taught by people who assume that you are already good at it.

If you're finding it difficult, I'd bet that is why. I wouldn't feel too bad about it -- like you said, everyone needs to start somewhere -- but it means it might be a good idea to sit down and work out the problem first before you write the code that does it.

Writing code that compiles without error is a good skill. How to break down an algorithm into computer-manageable chunks is another skill. You need to learn both. :)

Particularly when given an assignment to do something a certain way, we get so hung up on how to string together the commands and symbols, as requested by the assignment, that we don't give enough focus on the actual problem that needs solving.

The poster above that suggested you come up with an algorithm has good advice. I can't assume one way or another from what you've posted that you understand what needs to really be going on under the hood. Do you understand how to take a decimal (floating point) number and "process it" in order to determine how to round it? Are you able to do it on paper and write down, in plain english, what steps need to be taken?

That's how I start my algorithm functions. I write down in plain english the steps that need to be done. I usually write it as a comment chunk in the code file itself. Then I write the actual code to accomplish the steps I've written out, just below it. As a bonus, the algorithm is already documented!
 

lloyddean

macrumors 65816
May 10, 2009
1,001
16
Des Moines, WA
First, how, given a property of the base 10 number system, would you describe to us how you might multiply,, and then divide, the number 1.234 by 10 or 100 or 1000 in your head.

Second, do you know what the Standard C Library routine 'pow' does?
 

SkippyThorson

macrumors 68000
Original poster
Jul 22, 2007
1,513
498
Utica, NY
nojustjay, thank you very much for the kind words. I think that's just what I needed to hear. I believe, and my grades reflect, that I am just above the middle of the class average. Not great, but not awful.

Like I said a short time back, I saw Xcode for the first time in January, and I'm just trying to get the hang of it. She's older, and in a way, talking down to the students, because she really knows the stuff.

First, how, given a property of the base 10 number system, would you describe to us how you might multiply,, and then divide, the number 1.234 by 10 or 100 or 1000 in your head.

Second, do you know what the Standard C Library routine 'pow' does?
In my head, 1.234 * 10; since it's a 10, the decimal is just going to get kicked back one place, for the one 0, making 12.34. 100, two places, 1000, three.
1.234 / 10; the decimal will get kicked forward one place, making .1234. Again, 100, two places, 1000, three.

pow; Yes, that much she did explain. pow(10,2) for instance is 10 raised to 2. 10*10. I sort of see where you're going with this.
 

SkippyThorson

macrumors 68000
Original poster
Jul 22, 2007
1,513
498
Utica, NY
So now I think I'm on to something. With all the clues here and a good read through my book, I've arrived at the following three steps. I've been fiddling with them, but unsure about how they really all work together.

Code:
#include <stdio.h>
#include <math.h>
int main(void)

{
//variables
	int rounded_x;
	double x, y;
	double scale(double, int);
	
//input
	printf ("Welcome.\n");
	printf("Enter a positive number: \n");
//the number is set to x
	scanf("%lf", &x);
//user enters x
//----------------------------------------
	y = scale(x, 2);
//y is what is returned from scale using x and the power of 2
	rounded_x = (int) (x + .5);
//and now I'm unsure
	x = (double) scale(x, -2);
//----------------------------------------
	
//output
	printf("Rounded number is: %.4lf \n", x);
//end
	return 0;
}

//function outside of main
//double x and int n represent x and rounded_x
//scale_factor is a power of 10
double scale(double x, int n)
{
	double scale_factor;
	scale_factor = pow(10,n);
	return (x * scale_factor);
}