Want to win a PS4? Go Premium and enter to win our High-Tech Treats giveaway. Enter to Win

x
?
Solved

printf/scanf and decimals

Posted on 2003-12-09
15
Medium Priority
?
1,043 Views
Last Modified: 2011-09-20
//program to determine equal spacing for pickets

#include <stdio.h>    //scanf & printf
#include <conio.h>    //getch
# include <ctype.h>    //toupper

#define TRUE 1
#define FALSE !TRUE

char stay_open,c;

float distance,width,pickets,spacing,last_space;

void main()
{
      stay_open = TRUE;
      while (stay_open)
      {
      printf("\nEnter distance between posts  ");  // 45.8399
      scanf ("%f",&distance);

      printf("\nEnter width of picket  ");
      scanf("%f",&width);                        //  1.5

      printf("\nEnter desired number of pickets  ");
      scanf("%f",&pickets);                          // 30

/*  The formula for determining how to evenly  space  pickets between 2 posts is:  */
      spacing = ( (distance - (pickets * width) )  / (pickets + 1) );

      /*  Using the above entries, the true value of "spacing" is .02709358.  Rounded off to .0271   (%.4f) */
      printf("\n\nSpace pickets %.4f  ", spacing); //Space pickets .0271
      //printf("\n\nSpace pickets %.8f  ", spacing);

/*  The formula for determining the measurement of the last space is:  */
            last_space = ( distance - ( (pickets * spacing) + (pickets * width) ) );
/*Here is the problem to solve.  When determining the "last_space", the true value (.02709358) of "spacing" is not the correct value to use.  The value needed now is the "rounded off" value (%.4f .0271).  How can this be done? */
           printf("\n\nLast space is %.4f  ", last_space);
      //printf("\n\nLast space is %.8f  ", last_space);
      printf("\n\nStay Open? Any key for YES, N for NO.");
      c=toupper(getch());
      if(c == 'N')
      {
      stay_open=!TRUE;
      printf("\nAdios");
      }
          }
}




0
Comment
Question by:FrawgLips
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 5
  • 4
  • 2
  • +2
15 Comments
 
LVL 19

Expert Comment

by:Dexstar
ID: 9908561
@FrawgLips:

> /*Here is the problem to solve.  When determining the "last_space", the true
> value (.02709358) of "spacing" is not the correct value to use.  The value
> needed now is the "rounded off" value (%.4f .0271).  How can this be done? */

Try this code:
     spacing = (float)(((int)((spacing * 10000) + 0.5f)) / 10000);
     printf("\n\nSpace pickets %.4f  ", spacing); //Space pickets .0271
     last_space = ( distance - ( (pickets * spacing) + (pickets * width) ) );


Hope That Helps,
Dex*
0
 
LVL 44

Expert Comment

by:Karl Heinz Kremer
ID: 9908671
Dexstar's method is the one that I would have proposed as well. Just in case you are not clear on how it works:

The multiplication with 10000 "pulls" the four decimals you are interested in to the left side of the decimal point. After that you round the value by converting to an int (this will get rid of the fifth and so on decimal places). After that you divide by the same value that you first multiplied with to get back to the original value, but now rounded the way you wanted to. You can adjust the precision by e.g. using 100 to get two decimal places and so on.
0
 
LVL 84

Expert Comment

by:ozo
ID: 9909658
That works if we can assume the spacing is not negative
0
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 

Author Comment

by:FrawgLips
ID: 9912559
Thanks to all for response.

spacing = (float)(((int)((spacing * 10000) + 0.5f)) / 10000);

Dex*,   I cut and pasted  your code into mine....
the result was
"Space pickets .0000"
"Last space is .8399"
____________________
distance = 45.8399
width = 1.5
pickets = 30

Using a calculator and rounding off to 4 decimal places, the formula for spacing=.0271.  This is correct.

pickets * spacing = .813     (30 * .0271)
pickets * width = 45           (30 * 1.5)

45.8399 - 45.813 = .0269
(distance -  ( (pickets*spacing)+(pickets*width) ) )= .0269 this too is correct.  
Can you be more precise as to how to convert a float to an int and do I need to replace ("float") ((("int")with variables  to obtain these results?

Thanks again,
FL
   

 



0
 
LVL 44

Expert Comment

by:Karl Heinz Kremer
ID: 9913152
OK, I finally compiled your program (I did change getch() to getchar(), because I don't have conio.h).
It does report the correct values, even without the explicit rounding. Both the "SPace pickets" and "Last space" is reported as 0.0271.
Does your compiler generate something different?
0
 

Author Comment

by:FrawgLips
ID: 9913792
Yes, my compiler generates the same thing.   .0271 for both "spacing" and "last_space".  It is not totally correct though.  In this example "spacing" is correct but "last_space" should be .0269.  The problem is when "pickets" is multiplied by "spacing" because "spacing" is still an 8 digit decimal.......not rounded off to 4 decimal places.  
For "last_space" to be correct, (pickets * spacing) should be
(30 * .0271).......not  (30 * .02709358).
In this example, all I want to see for "last_space" is .0269....how can that be accomplished using the 2 formulas shown previously?

Thanks,
FL  
     
0
 
LVL 17

Expert Comment

by:rstaveley
ID: 9914195
They should be the same:

if      s = (d-pw)/(p+1);
=>   sp+s = d-pw;
=>   s = d - ps - pw;
=>   s = d - (ps + pw);
=>   s = (d - ((p  * s ) + (p * w) ) )    [Using C notation here]

s = spacing
d = distance
p = pickets
w = width
0
 

Author Comment

by:FrawgLips
ID: 9915175
To double check the math:
multiply spacing (.0271) * pickets (30) = .813
Then add pickets (30) * width (1.5) = 45
Total is 45.813....subtracted from 45.8399 = .0269 (last_space).
There is always 1 space more than pickets....that's the reason for part of the formula being  ........ / (pickets +1).  OK, we have 31 spaces * .0271 = .8401.  Plus the space being taken up by the 30 pickets = 45 (30 * 1.5)
45 + .8401 = 45.8401 - 45.8399 = .0002.  Since 45.8401 > 45.8399 we know the last space will be .0002 smaller.

On the other hand, if we multiply the 31 spaces * .027093548(actual value)  = .8399.   + 45 = 45.3899.  Bingo! Right on...The problem is we are limited to 4 decimal places.  So, we must round off that 9 digit decimal (Not 8.  I gave the wrong actual value in my question) to 4 digits and then use the rounded off number for all further calculations.

I don't understand the (float)(((int) ........+ 0.5f....etc.

As you all can tell, I don't have the answer yet.  For anyone with further comments, suggestions etc: don't assume I know anything....spell it out....Thanks
FL



 
 
 
0
 
LVL 17

Expert Comment

by:rstaveley
ID: 9915286
I think your formula is wrong. Check my logic. The two expressions are equivalent.

if      s = (d-pw)/(p+1);
=>   sp+s = d-pw;             Multiply both sides by (p+1)
=>   s = d - ps - pw;          Subtract ps from both sides
=>   s = d - (ps + pw);       Use parenthesis... and this is your other expression, is it not?

It has been way too long since I was at school. Correct me if I'm wrong.
0
 

Author Comment

by:FrawgLips
ID: 9916774
Look at your hand.  The thumb and little finger are the posts...you have 3 "pickets" and 4 spaces.  To determine the spacing you subtract the total width of all pickets from the distance between the posts then divide by 4. This gives the spacing.

To doublecheck you multiply the spacing * 3 (not 4) then add the total width of all pickets to that.  (spacing*pickets) +(pickets*width)
subtracted from distance between posts = the 4th space..... (last_space)....... (pickets+1) is used only for determining total spacing.

In most cases the last_space is not equal to any other space...this program is to determine what adjustments are necessary to get all pickets within .0001 of each other.  Sometimes only 1 picket needs adjusting.  Other times several may need adjusting.  It depends on how many .0001's difference there is between "spacing" and "last_space".  If  the difference is .0007 then 6 pickets need adjusted  by .0001 each. (adjusting 6 pickets changes 7 spaces)

The difference between the 2 (spacing  and  last_space) is the key to making this program work....I just need to zap about 5 decimal places after rounding off.

If you still think the formula is wrong, I won't wait for you to call me to build you a picket fence.....I will paint it for you though...lol

FL

0
 
LVL 19

Accepted Solution

by:
Dexstar earned 1000 total points
ID: 9917050
@FrawgLips:

Okay, there was a mistake in my answer before.  The line should read like this:
      spacing = ((int)((spacing * 10000.0f) + 0.5f)) / 10000.0f;

If you can't understand what that line does, here it is written out as 4 lines:
      spacing *= 10000.0f;
      spacing += 0.5f;
      spacing = (int)spacing;
      spacing = spacing / 10000.0f;

Using 45.8399, 1.5, and 30 for the input values, here are the values of spacing at each step:
      spacing = ( (distance - (pickets * width) )  / (pickets + 1) );      /* spacing = 0.027093580 */
      spacing *= 10000.0f;                              /* spacing = 270.9358 */
      spacing += 0.5f;                              /* spacing = 271.4358 */
      spacing = (int)spacing;                        /* spacing = 271.0000 */
      spacing = spacing / 10000.0f;                        /* spacing = 0.027100 */

When you cast a float as an Int, in drops off any decimal value that is there.  You add .5 to it so that it rounds properly when you chop off the decimal value.  The multiply by 10000 gets the digits you want to keep on the other side of the decimal so they don't get lost, and the divide by 10000 puts them back where they are supposed to go.

If you let the program run, this is the output:
      Space pickets 0.0271
      Last space is 0.0269

Isn't that correct?

Dex*

0
 
LVL 19

Expert Comment

by:Dexstar
ID: 9917085
> That works if we can assume the spacing is not negative

@ozo:  Give me an example where spacing could possibly be negative, and I'll rewrite to handle it.  :)

Peace,
Dex*
0
 
LVL 84

Expert Comment

by:ozo
ID: 9917321
distance=10
width=3
pickets=8
0
 

Author Comment

by:FrawgLips
ID: 9917334
Good job Dex*,

Negative spacing is not a prob.  It would be the result of entering a wrong value or possibly trying to put too many pickets in between the posts in which case no code known to man could handle it...lol

Since I learned more than I asked for and it is the Holiday Season, have another 100 points....Happy Holidays to all....

Greatly appreciate your efforts,
FL
 :o)  
0
 
LVL 19

Expert Comment

by:Dexstar
ID: 9917360
:)

Thank you very much!  Glad you got what you wanted!

Dex*
0

Featured Post

Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

An Outlet in Cocoa is a persistent reference to a GUI control; it connects a property (a variable) to a control.  For example, it is common to create an Outlet for the text field GUI control and change the text that appears in this field via that Ou…
Examines three attack vectors, specifically, the different types of malware used in malicious attacks, web application attacks, and finally, network based attacks.  Concludes by examining the means of securing and protecting critical systems and inf…
The goal of this video is to provide viewers with basic examples to understand and use pointers in the C programming language.
The goal of this video is to provide viewers with basic examples to understand and use structures in the C programming language.

597 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question