1

I asked this question before now, when i first asked this question I didnt know what the problem was but I know and I have tried to read through Is floating-point math broken? and Why Are Floating Point Numbers Inaccurate? they showed the reason for the problems but I didn't really see anyway to bypass this problem in the code I have written so now I am asking if any body knows what I should do to the code to make the program work. The code and description below

The idea behind this program is for it to find the value of two doubles a and t, where if they were multiplied they give a specified value. So if the specified value was 4 the program has to find the values of a and t, where if they were multiplied it would give 4. The variable t is in a range of 5 to 10.

I wrote the following code

int main(void)
{
    double a = 0.01;
    double t = 5;
    while(1){
        if(t * a != 4){
            t = t + 0.01;
            if(t > 10){
                t = 5;
                a = a + 0.01;
            }
        }
        else if (t * a == 4){
            break;
        }
    }
    printf("%f %f", t, a);
    return 0;   
}

The code doesn't seem to work if I i try to increment the values using 0.01 although it works if the value of increment is 1. I know the reason this happens but how would I fix this in this program code or are there are other ways I could do write the code?. The code just seems to loop forever

  • 4
    Note that *"The code doesn't seem to work"* is never sufficient problem description. What happened? What did you expect to happen? – user694733 May 26 '16 at 07:20
  • 2
    What's not working? Can you say what you expect and what you are getting? – Wayne Booth May 26 '16 at 07:22
  • `t * a` might never me _exactly_ 4. If you have read the "Is floating-point math broken" article you should know that. – Jabberwocky May 26 '16 at 07:23
  • http://stackoverflow.com/questions/7408566/java-double-value-0-01-changes-to-0-009999999999999787 – Abhineet May 26 '16 at 07:23
  • Better try using float, but then again, it won't give you a perfect desired value but would be much more near to the desired value. – Abhineet May 26 '16 at 07:24
  • 2
    You are lacking elementary debugging skills. Insert `printf("%lf %lf %lf\n", t, a, t * a);` at the beginning of your while loop, and you'll see what happens. – Jabberwocky May 26 '16 at 07:29
  • You need to compare within an interval and use an "epsilon value". There are plenty of answers about that if you just do some research. See [this](http://stackoverflow.com/questions/10334688/how-dangerous-is-it-to-compare-floating-point-values) for example. – Lundin May 26 '16 at 07:33
  • 1) do not perform `==` with double values, it will (almost) always fail 2) this line: `if(t * a != 4){` is comparing a double value to an integer. Suggest: `if(t * a != 4.0){` Fortunately, the precedence of C says that `*` is higher than `!=`, but the code, for clarity, should wrap the `t * a` in parens . – user3629249 May 28 '16 at 02:53
  • when assigning and comparing values to `t`, always use `double` values, not integers. so, the following lines need to be corrected: `double t = 5;` `if(t > 10){` `t = 5;` and `else if (t * a == 4){` – user3629249 May 28 '16 at 02:56

2 Answers2

3

Instead of using equality between two doubles use a small range.

#include <math.h>
#include <stdio.h>

int main(void)
{
    double a = 0.01;
    double t = 5.0;
    double epsilon = 0.000001;
    while(1){
        if(fabs(t * a - 4.0) < epsilon){
            break;
        }
        else{
            t = t + 0.01;
            if(t > 10){
                t = 5;
                a = a + 0.01;
            }
        }
    }
    printf("%f %f %f", t, a, a*t);
    return 0;   
}

Note that fabs(x - y) < epsilon is equivalent to (y - epsilon) < x && x < (y + epsilon), so you're checking whether x falls in a very small interval around y.

Nishant
  • 2,571
  • 1
  • 17
  • 29
-1

if a * t is 4 then a will be 4/t. Now if t is in the range of 5 to 10 and can take values 5.1, 5.2 etc, then a will have a corresponding value for every value of t.

i.e. for t = 5.1 a = 0.78431

for t = 5.2 a = 0.7692.

You can run a loop to print the values of a for each value of t

t = 5.0;
for (i=0; i<50; i++)
{
   t += 0.1;
   a = 4/t;
   printf ("%f %f",a,t);
}
Rishikesh Raje
  • 8,556
  • 2
  • 16
  • 31
  • While this answer does solve this specific problem, this is akin to giving OP a fish rather than teaching them how to catch it. The question is really about how to determine FP equality in general, not about solving `a * t == 4` given `5 <= t && t < 10 && 0 < a`. –  May 26 '16 at 08:04