Click here to Skip to main content
15,887,027 members
Please Sign up or sign in to vote.
1.00/5 (2 votes)
See more:
please explain how it works? The program gives me the correct result only when I add integers, but in my task I would prefer to use the type double.

working option:
`
C++
for (int i = -10000; i < 10000; i++) {
    formula = s1 / (v1 + k) + s2;
    if (formula == 0) {
        break;
}
    k += 1;
}

Result:3.000000
`

it doesnt work correctly:
`
C++
for (int i = -10000; i < 10000; i++) {
    formula = s1 / (v1 + k) + s2;
    if (formula == 0) {
        break;
}
    k += 0.00001;
}

Result:0.200000
`

What I have tried:

in my program I need a more precise result so I can't use the type int.
Posted
Updated 19-Mar-24 11:02am
v3
Comments
Mike Hankey 19-Mar-24 16:27pm    
K +=1; in the working version and K == 0.00001 in the non working version?
Саша Гайдамак 19-Mar-24 16:27pm    
yes
jeron1 19-Mar-24 16:36pm    
What value is displayed in the Result line?
Саша Гайдамак 19-Mar-24 16:38pm    
with the first variant of program: Result:3.000000 (correct)
with the second: Result:0.200000
jeron1 19-Mar-24 16:40pm    
Is 'k' being displayed or 'formula' or something else?

Step one is to make sure the variables formula, s1, s2, v1, and k are all of type double. You actually don't need all of them to be doubles but you want to make sure the result (formula) is a double and the division must be done with doubles. An integer result there will be almost guaranteed to give errant results.

Step two is to beware of equal comparisons with double values ie., testing if formula is zero. The usual technique for this is to define an epsilon value which means "close enough" and compare with that. Here is an example :
C++
const double epsilon = 1.0E-9;

// do calculations here

double delta = fabs( formula );
if( delta < epsilon )
    break;
This will break out of the for loop if formula is in the range between -1E-9 and +1E-9. You can use 1.0E-6 or other values for epsilon as long as it is within your desired computational tolerance.
 
Share this answer
 
There are several things to note here. It seems that only the variable k is changed with each loop.
C
for (int i = -10000; i < 10000; i++) {
  formula = s1 / (v1 + k) + s2;
  if (formula == 0) {
	break;
  }
  k += 0.00001;
}

Unfortunately, the value k += 0.00001 cannot be stored exactly as a float (or double), so the compiler usually uses the closest value. If you now add up these not exactly matching double numbers, the error in the sum increases with each loop.

There are now several ways to solve the problem.
1. instead of constantly adding again, it is better to multiply once by the slice index, which increases the accuracy considerably.
2. instead of comparing two floats directly with each other, it would be better to check the difference, whereby the difference often does not become 0, but should fall below a specified value.

Using double instead of float for better accuracy would only shift the problem, not solve it.
 
Share this answer
 
v2
Comments
Rick York 19-Mar-24 18:31pm    
That sounds about right to me. +5.
merano99 20-Mar-24 2:40am    
Thx!Your comment that all variables should be float or double is important. I would have assumed that.
 
Share this answer
 
Comments
VaKa 21-Mar-24 6:13am    
i think problem described here is more in math than programming, but Every Computer Scientist Should Know About Floating-Point Arithmetic ^)
merano99 21-Mar-24 18:41pm    
You are absolutely right, and on closer inspection several problems overlap here.
as i dont know initial values for formula, s1, v1, k, s2
and looking at 1st example code,
i suppose that cycle stops within 3 steps with incerment=1 (supposing k=0 at begininig), and resulting k is 3.

at 2nd example of code, k increments with 0.00001 and within same cycle (from -10000 to 10000) never rich value of 3 - when cycle ends (executing all 20'000 steps) value of k is only 0.2

as we can see at output

so if we want get same output we should increase steps count at least 3 / 0.2 +1 = 16 times

as values of s1,s2,v1 may changing from task to task we could use do-while loop

const double epsilon = 1.0E-9;

do {
    formula = s1 / (v1 + k) + s2;
    k += 0.00001;
} while (formula > epsilon)


or we shoold increase speed of increasing of k
 
Share this answer
 
Comments
merano99 22-Mar-24 14:33pm    
Since the questioner knows that the result 3.0 is correct, he should have told us his constants and the start value.
I have thought about why the loop starts at -10000 and come to the conclusion that it is better to calculate k with the loop index i. k = offset + k_step*i
If you were to add Rick's and my solutions to your approach, you would have to check (fabs(formula) > epsilon), calculate k with the loop index and, as you correctly described, increase the range of the loop to such an extent that the supposedly correct result 3.0 has a chance.
I'll wait and see if my comment has any effect on your suggestion before voting.
VaKa 22-Mar-24 15:23pm    
i'm just trying to say, that problem not in variable storing format (double or float), but in realization as well.

just compile and run:
    double formula, s1, v1, s2;
    double k;
    double kInc;

    // supposing initial values
    kInc = 0.00001;
    k    =  0.0;
    s1   = -5.0;
    v1   =  2.0;
    s2   =  1.0;

    const double epsilon = 1.0E-6;

    for(int i = -10000; i < 400000; i++) 
    {
        formula = s1 / (v1 + k) + s2;

        if( fabs(formula) < epsilon)
        {
            break;
        }

         k += kInc;
    }

    printf("\n\nResult: %f (i=%d, cycles: %d) => formula=%f\n\n", k, i, int(k/kInc), formula);


    // output
    // >>
    //     Result: 3.000000 (i=290000, cycles: 300000) => formula=0.000000
merano99 22-Mar-24 18:15pm    
In your proposed solution, you are already assuming that k is positive. The search starts asymmetrically at 0.
Usually, however, the solution is not known and I would read the (poorly implemented) approach of the questioner with the asymmetric loop in such a way that the solution could actually also be negative.
Your approach would also not find any negative solutions.

Another point is that the extremely frequent summation or subtraction in the floating point range can generate high errors.

Starting from a symmetrical loop with for ( i = -310000; i < 310000; i++) the result would be with your approach with k += kInc;
i = -10000
formula = 2.2370993946196904e-12
k = 3.0000000000111862


If you do not add up, but multiply by the loop index, the result looks like this with k = i*kInc:
i = 300001
formula = 0.0000000000000000
k = 3.0000000000000004

Please bear in mind that my proposed solution covers a much larger area, which would have led to the following result with your solution:
i = 300000
formula	= 4.6054271507500744e-12
k = 3.0000000000230274
VaKa 23-Mar-24 15:29pm    
im writing here not for stars, but to point out that for-range size not enough to rich right result.
for-range size is primary problem, despite other mistakes.
why i say that? because without understanding that, all other mistakes had no chance to be understood and corrected.

sorry for pure english.
peace to all of you!

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900