For with minor or equal condition in C++ [duplicate] - c++

This question already has answers here:
Is floating point math broken?
(31 answers)
Closed 5 years ago.
I am doing a loop to perform some calculations from t=0 to t=1 (included).
That should be easy like this:
for(double t = 0; t<=1; t = t + 0.05)
{
DEBUG_LOG1 (LVL1, t);
//DoMaths
}
But for some reason, t is being logged from 0 to 0.95, not including t=1, as it if was t<1 instead of t<=1.
Where is the problem in my code?

This is a simple problem with types. Because it is a floating point number will will likely never get precisely 0.05 or 1.00.
Rather you'll it will try for 0.05 but really will be something like 0.050000000000000012 which added together 20 times is not 1 but more like 1.00000000000000024 and will therefore not correspond with 1.
There is not problem with your code per se since you catch the problem by using <= instead of =.
You can read more about floating point numbers on http://www.learncpp.com/cpp-tutorial/25-floating-point-numbers/

I think it may be because 0.05 is not exactly representable as a floating point value. It is only approximate. Try running this program.
#include <stdio.h>
int main()
{
double x = 0.05;
printf("%.50lf\n", x);
return 0;
}
Here I tell printf to give me a lot of excess precision. This prints out the value
0.05000000000000000277555756156289135105907917022705.
Now if I take that value and multiply and add 0.5 to it 19 times in a loop I get...
1.00000000000000022204460492503130808472633361816406
See how it is not exactly 1 but slightly greater. This is the reason comparing equality between floats leads to strange results. You can get around this by adding a small epsilon to 1. For instance compare to 1.001 in your loop.

Decimal numbers can't be accurately represented using floating types. For example 0.05 can't be accurately represented in type double and depending on the platform it might be: 0.050000000000000003 or similar. So that tiny little bit always gets added in your loop. By the time you think it is 0.95 it is actually 0.95000000000000029 or similar and adding 0.05 makes it greater than 1, hence the observed results. More info on the subject in this SO post:
Is floating point math broken?

Related

How make a good calculator with floating point arithmetic [duplicate]

This question already has answers here:
Is floating point math broken?
(31 answers)
Closed 4 years ago.
Here is how my calculator should work:
There is a JSON value where I can write the first multiplier - something like this:
{
"value1": 1.4
}
On the calculator I can write the second multiplier - only 10^n numbers (10, 100, ..., 10000000). And my calc should return me an integer, as I know that always people who use my calc with write less numbers after the decimal point for the first multiplier than we have 0s on the calc for the second multiplier. Yes, my calc is a very-very strange one.
Here are valid inputs:
v1=1.4; v2=100;
v1=1.414; v2=100000;
v1=1.1; v2=100;
What happens when I do this, for example for value1=1.4 and value2=10000 I get 13900. As far as float cannot hold any number sometimes it stores different numbers. For 1.4 internally it stores 1.399999 on my machine. I know why, but you know the QA engineer who tests my app tells me that I need to get 14000. Your calc does not work. How to make my calc so that I will print correct number?
P.S. Of course I have cut out my real problem from the context but the thing is that I have a float in a file and a 10^n number in my program as a user input. How to get correct result?
EDIT1: I don't ask why float works that way. I know why. I ask how to solve the problem even when float works that way.
EDIT2: I use RapidJson to read the JSON file which already returns me wrong number as a double precision number. I can't use libraries that provide with higher precision floating points.
Round the result when you format it for display. A double precision value is correct to about 15 significant digits, so if you round the result to 12 significant digits you're not going to surprise the user.

gfortran REAL not accurate to 8 decimal places [duplicate]

This question already exists:
gfortran represents REAL incorrectly [duplicate]
Closed 8 years ago.
This question has not been previously answered. I am trying to represent a real or any number for that matter in Fortran correctly. What gfortran is doing for me is way off. For example when I declare the variable REAL pi=3.14159 fortran prints pi = 3.14159012 rather than say 3.14159000. See below:
PROGRAM Test
IMPLICIT NONE
REAL:: pi = 3.14159
PRINT *, "PI = ",pi
END PROGRAM Test
This prints:
PI = 3.14159012
I might have expected something like PI = 3.14159000 as a REAL is supposed to be accurate to at least 8 decimal places.
I'm in a good mood, so I'll try to answer this question, which is basic knowledge which can be easily googled (as already pointed out in the comments to this and your former question).
Luckily, Fortran provides some really interesting intrinsics to get some understanding of floating point numbers.
The 8 digits, you are talking about, are a rule of thumb and can be related to the function EPSILON(x), which prints the smallest deviation from 1, which can be represented within the chosen model (e.g. REAL4). This value is actually 1.19e-7 which means, that your 8th digit is most likely wrong. I write most likely, because some numbers can be represented exactly.
In the case of PI, the smallest representable deviation can be printed using the intrinsic SPACING(PI). This shows a value of 2.38e-7, which is slightly larger than the epsilon and still allows for 7 correct digits.
Now, why does your value of PI get stored as 3.14159012? When you store a floating point number, you always store the nearest representable number.
Using the value of spacing, we can get the possible values for your pi. Possible numbers and their differences to your value of 3.14159 are:
3.14158988 1.20E-007
3.14159012 -1.18E-007
3.14159036 -3.56E-007
As you can see, 3.14159012 is the nearest possible value to 3.14159 and is thus stored and printed.
It is common for the last two digit to be erroneous. It is called floating point error.
Check this:
Week 1 - Lecture 2: Binary storage and version control / Fixed and floating point real numbers (9-08).mp4
#
https://class.coursera.org/scicomp-002/lecture

Dividing a float by 10 [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Why can't decimal numbers be represented exactly in binary?
I am developing a pretty simple algorithm for mathematics use under C++.
And I have a floating point variable named "step", each time I finish a while loop, I need step to be divided by 10.
So my code is kind of like this,
float step = 1;
while ( ... ){
//the codes
step /= 10;
}
In my stupid simple logic, that ends of well. step will be divided by 10, from 1 to 0.1, from 0.1 to 0.01.
But it didn't, instead something like 0.100000000001 appears. And I was like "What The Hell"
Can someone please help me with this. It's probably something about the data type itself that I don't fully understand. So if someone could explain further, it'll be appreciated.
It is a numerical issue. The Problem is that 1/10 is a endless long number in binary and the successive apply of a division by 10 ends up with summing the error in each step. To get a more stable version you should multiply the divisor. But take care: the result is also not exact! You may want to replace the float with a double to minimize the error.
unsigned int div = 1;
while(...)
{
double step = 1.0 / (double)div;
....
div *= 10;
}
The division by ten cannot be exact for binary floating point arithmetic, so you see results that will look a little bit off from what you expect.
Binary floating are represented as an integer ratio where the denominator is a power of two. Since there in no binary fraction exactly equal to one-tenth, you'll see the nearest representable number instead of the one you expected.

Rounding Decimals to whole numbers

I was looking around and could not find exactly what I was looking for.
I want to round all my numbers up to the whole number.
Example:
5.9 would be 6
5.5 would be 6
5.1 would be 6
5.000001122 would be 6
5.0 would be 5
I was thinking if I put them into ints that would get rid of the decimal but it did not look right as the decimals were just dropping off. Am I correct here?
So I thought about just doing that then adding 1 to the final result which would fix about 99% of the problem but if my result is 5 I do not want to add 1 to it.
How would I go about fixing this issue I have?
You're looking for the ceil() function from <math.h> or std::ceil() from <cmath>.
[...] but it did not look right as the decimals were just dropping off. Am I correct here?
Correct, casting to an int simply discards the fractional part (i.e. rounds toward zero).
While std::ceil() from cmath will work for all the examples in your question, the question does not specify the required behaviour for negative values. For example should -5.9 round to -6.0 or -5.0? ceil(-5.9) = 5.0, which may not be what you want. If you want -6.0, then you would need floor(-5.9), so the code would have to be:
round = f > 0 ? std::ceil(f) : std::floor(f) ;
The question is whether you are rounding up as ceil() does, or rather rounding away from zero (up in magnitude rather than up in value) which the above code does?
Use math.h function ceil(number)

Incorrect floating point math?

Here is a problem that has had me completely baffled for the past few hours...
I have an equation hard coded in my program:
double s2;
s2 = -(0*13)/84+6/42-0/84+24/12+(6*13)/42;
Every time i run the program, the computer spits out 3 as the answer, however doing the math by hand, i get 4. Even further, after inputting the equation into Matlab, I also get the answer 4. Whats going on here?
The only thing i can think of that is going wrong here would be round off error. However with a maximum of 5 rounding errors, coupled with using double precision math, my maximum error would be very very small so i doubt that is the problem.
Anyone able to offer any solutions?
Thanks in advance,
-Faken
You're not actually doing floating point math there, you're doing integer math, which will floor the results of divisions.
In C++, 5/4 = 1, not 1.25 - because 5 and 4 are both integers, so the result will be an integer, and thus the fractional part of the result is thrown away.
On the other hand, 5.0/4.0 will equal approx. 1.25 because at least one of 5.0 and 4.0 is a floating-point number so the result will also be floating point.
You're confusing integer division with floating point division. 3 is the correct answer with integer division. You'll get 4 if you convert those values to floating point numbers.
Some of this is being evaluated using integer arithmetic. Try adding a decimal place to your numbers, e.g. 6.0 instead 6 to tell the compiler that you don't want integer arithmetic.
s2 = -(0*13)/84+6/42-0/84+24/12+(6*13)/42;
yields 3
s2 = -(0.*13.)/84.+6./42.-0./84.+24./12.+(6.*13.)/42.;
does what you are expecting.