Link to home
Start Free TrialLog in
Avatar of FrawgLips
FrawgLips

asked on

printf/scanf and decimals

//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");
      }
          }
}




Avatar of Dexstar
Dexstar

@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*
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.
Avatar of ozo
That works if we can assume the spacing is not negative
Avatar of FrawgLips

ASKER

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
   

 



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?
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  
     
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
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



 
 
 
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.
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

ASKER CERTIFIED SOLUTION
Avatar of Dexstar
Dexstar

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
> 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*
distance=10
width=3
pickets=8
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)  
:)

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

Dex*