How do I solve this for loop in C++? [duplicate] - c++

This question already has answers here:
Is floating point math broken?
(31 answers)
How dangerous is it to compare floating point values?
(12 answers)
Closed 7 years ago.
for(float i=1; i<=1.5; i+=0.1)
{
// statements
}
The above C++ for loop runs for 5 times. Shouldn't this run for 6 times?

This is a great example of a floating point precision error. Precise values like multiples of 0.1, 0.2 cannot be precisely represented internally in the computer's memory. You'll want to do a comparison using EPSILON (http://en.cppreference.com/w/cpp/types/numeric_limits/epsilon)
Something like
for (float i = 1; fabs(1.5 - i) < EPSILON; i+=0.1) {
//statements
}

It is because multiples of 0.1 cannot be presented precisely in binary, and the actual value stored is an approximation that may be slightly less than 0.1. So, 5*0.1 might be less than 0.5 or it might be more (depending on how the floating point values are represented).
It is usually a really bad idea to use a floating point variable (and tests involving equality or inequality of floating point values) to control loops at all. Effects can include running more (or less) times that intended, or - in some bad cases - an infinite loop where a finite number of runs was expected.
In your case, you would be better off doing something like
for (int i = 0; i < 5; ++i)
{
float value = 1.0 * i*0.1;
// use value here rather than the i in your original code
}
Alternatively, you can use some test that allows for the imprecision of floating point (e.g. compare i - 1.5 with some value such as machine epsilon). The catch with this is that the actual number of iterations still potentially has some level of unpredictability, particularly in loops that involve a large number of iterations (e.g. iterating from 1.0 to 50000.0 in steps of 0.01) because rounding errors can either accumulate or cancel out at different stages during the loop.

Related

Modern practice to compare double/float for equality in modern C++ [duplicate]

This question already has answers here:
What is the most effective way for float and double comparison?
(34 answers)
Floating point comparison revisited
(4 answers)
Is < faster than <=?
(16 answers)
Closed 1 year ago.
if (std::abs(double1 - double2) < std::numeric_limits<double>::epsilon())
std::cout<<"Equal";
else
std::cout<<"Not equal";
Is this code with modern C++11/14/17/21 is still the way we should compare float and doubles, or now it's ok just to write
if (double1 == double2)
And compiler will handle the epsilon issue for us?
BTW: is it better to write < or <= when checking against epsilon?
Is this code with modern C++11/14/17/21 is still the way we should compare float and doubles, or now it's ok just to write if (double1 == double2) And compiler will handle the epsilon issue for us?
Both approaches function the same in modern C++ as they did in early C++.
Both approaches are also flawed.
Using == assumes that your code has accounted for any floating point rounding errors, and it's very rare/difficult for code to do that.
Comparing against epsilon assumes that a reasonable amount of rounding error will be less than the constant epsilon, and that is very likely a wrong assumption!
If your numbers have magnitude greater than 2.0, your epsilon trick will be no different from direct comparison, and have the same flaws. Regardless of whether you use < or <=.
If your numbers have the same sign and a magnitude smaller than epsilon, your epsilon trick will say they are always equal, even if one is hundreds of times larger than the other. They would both be equal to zero, too.
A wise approach may be to avoid writing code that depends on whether floating point numbers are equal. Instead test if they are relatively close, by some factor.
The code below will test whether two numbers are within about 0.01% of each other. Regardless of their scale.
const auto relative_difference_factor = 0.0001. // 0.01%
const auto greater_magnitude = std::max(std::abs(double1),std::abs(double2));
if ( std::abs(double1-double2) < relative_difference_factor * greater_magnitude )
std::cout<<"Relatively close";
else
std::cout<<"Not relatively close";

Why does it seem like my floating point value is not equal to itself? [duplicate]

This question already has answers here:
strange output in comparison of float with float literal
(8 answers)
Closed 4 years ago.
#include<iostream.h>
using namespace std;
int main()
{
float x=1.1;
if(x==1.1)
cout<<"yes";
else
cout<<"no";
return 0;
}
I assign value 1.1 to x and checked value of x is 1.1 or not?
You've wandered into an interesting area of almost all programming languages. Floating point values are tricky things, and testing them for equality is very rarely recommended. The basic problem is that floating point values on modern computers are represented as binary decimals with a finite number of digits of precision.
To make this simpler to understand, lets work with base 10 decimals and use a number that can't be accurately represented using them. Take 1/3. If you are representing it as a base 10 decimal you get this:
0.̅3 (there is a bar over the three if it isn't showing up properly). Basically, it goes on forever, there is no finite number of digits that can represent 1/3 as a base ten decimal with perfect accuracy. So, if you only have so many digits, you chop it off and approximate:
0.333333
That's actually 333333/1000000, which is really close to 1/3, but not quite.
C++ has a few different floating point types. And these types usually (it depends on the platform the program is being compiled for) have different numbers of significant digits. By default, a floating point constant is of type double which usually has more digits than a float (and it never has less). Again, using base 10 as an example, since you were storing your value in a float you were doing something like this:
0.333333 == 0.3333333333333333333
which of course is false.
If you wrote your code this way:
#include <iostream>
using namespace std;
int main()
{
float x = 1.1f;
if(x == 1.1f)
cout<<"yes";
else
cout<<"no";
return 0;
}
you would likely get the expected result. Putting an f at the end of a bare floating point value (aka, a floating point literal) tells C++ that it's of type float.
This is all very fascinating of course, and there's a lot to get into. If you would like to learn a lot more about how floating point numbers are really represented, there is a nice Wikipedia page on IEEE 754 floating point representation, which is how most modern processors represent floating point numbers nowadays.
From a practical standpoint, you should rarely (if ever) compare floating point numbers for equality. Usually, a desire to do so indicates some sort of design flaw in your program. And if you really must than use an 'epsilon' comparison. Basically, test to see if your number is 'close enough', though determining what that means in any given situation isn't necessarily a trivial task, which is why it usually represents a design flaw if you need to compare them for equality at all. But, in your case, it could look like this:
#include <iostream>
#include <cmath>
using namespace std;
int main()
{
float x=1.1;
if (fabs(x - 1.1) < 0.000001)
cout<<"yes";
else
cout<<"no";
return 0;
}
The reason the compare fails is that you're comparing a double value to a float variable.
Some compilers will issue a warning when you assign a double value to a float variable.
To get the desired output, you could try this:
double x = 1.1;
if (x == 1.1)
or this:
float x = 1.1f;
if (x == 1.1f)

C++ for loop exercise [duplicate]

This question already has answers here:
Is floating point math broken?
(31 answers)
Closed 4 years ago.
Below you can find a basic C++ exercise with a for loop, the question is: what is the value of i after the loop runs. (Apparently, the value is 5.)
My question, on the 5th run (i=5), the value of a is 100, shouldn't the loop stop since the condition is a<100? Isn't the condition checked after a is multiplied with 10? (so after a is already 100)
If I check the value of a after the loop exit, it will be 1000. I am confused. Why does the loop not stop at 100?
#include <iostream>
using namespace std;
int main(void) {
float a;
int i = 0;
for(a = 0.01; a < 1e2; a *= 1e1)
++i;
return 0;
}
The exercise is designed to show that float (and double etc., floating point numbers in general) do not have the exact decimal value as what you see in the program text.
0.01 (decimal) cannot be exactly represented in the binary floating point format used, therefore multiplying 10 five times will not yield exactly 100.0.
See also: Floating point inaccuracy examples
You can't tell exactly what will happen with this code without knowing the details of the floating point implementation on your platform; the C++ standard leaves this intentionally flexible.
In essence 0.01 could be an approximation for the closest float to that double literal. So the stopping conditional a < 1e2 could be met prematurely or otherwise.
Note that along with 0.01, 1e1 is a literal of type double.
So the conversions to float are complicating things further. Then there is floating point strictness to consider.
Cut a long story short: don't use a floating point as the "index" in a loop.

Strange rounding behavior [duplicate]

This question already has answers here:
C++ floating point precision [duplicate]
(5 answers)
Closed 5 years ago.
I'm trying to round doubles to a specific precision, however the following functions give me different results:
Version 1:
static double RoundPrecision(double& val)
{
val = floor(val * 1000 + 0.5) * 0.001;
return val;
}
Version 2:
static double RoundPrecision(double& val)
{
val = floor(val * 1000 + 0.5) / 1000;
return val;
}
Example output when rounding the number 300.9:
Version 1: 300.90000000000003
Version 2: 300.89999999999998
Both versions sometimes give the same result, but for specific inputs the results differ. I have to have consistent behavior when equating numbers to other variables in the program.
EDIT:
I am aware of the problems with floating point precision, which is exactly what I'm trying to avoid here by rounding. I need a consistent way to round to 3 decimal point precision.
Computers are limited in their precision. You either accept the available precision in double or float, or you seek other libraries that give you sufficient precision, but with worse performance. Realistically, you cannot achieve exact real-numbers on computers, and you won't even need it. double gives you 10^-16 relative precision, then try long double. If that isn't enough, then seek external libraries that would do that for you. Here's an example of an arbitrary precision library.
From the comments I see that you need 3 decimal places precision. If you read this number up to 3 decimal points, then both results are the same. I think the reasons you're confused is that you don't know how to compare floats. Here's how you do it.

Increasing float value [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Floating point inaccuracy examples
I have the following line inside a WHILE loop, in C/C++:
while(...)
{
x = x + float(0.1); // x is a float type. Is the cast necessary?
}
x starts as 0. The thing is, after my first loop, x = 0.1. That's cool. After my second loop, x = 0.2. That's sweet. But, after my third loop, x = 0.3000001. That's not OK. I want it to have 0.3 as value, not 0.3000001. Can it be done? Am I looping wrongly?
Floating point does not work that way there are infinitely many real numbers between any two real numbers and only a finite amount of bits this means that in almost all cases the floating point representation is approximate. Read this link for more info.
It's not the loop, it's just how floats are represented in memory. You don't expect all real numbers to be directly representible in a limited number of bytes, right?
A 0.3 can't be exactly represented by a float. Try a double (not saying it will work, it probably won't, but the offset will be lower).
This is a common misconception with floating point numbers. 0.3 may not be exactly representable with 32bit or 64bit binary floating point. Lots of numbers are not exactly representable. Your loop is working fine ignoring the unnecessary syntax.
while (...)
{
x += 0.1f; /* this will do just fine in C++ and C */
}
If this doesn't make sense consider the fact that there are an infinite number of floating point numbers...with only a finite number of bits to describe them.
Either way, if you need exact results you need to use a decimal type of the proper precision. Good news though, unless you're doing calculations on money you likely do not need exact results (even if you think you do).
Code such as this:
for (int i = 0;… ; ++i)
{
float x = i / 10.f;
…
}
will result in the value of x in each iteration being the float value that is closest to i/10. It will usually not be exact, since the exact value of i/10 is usually not representable in float.
For double, change the definition to:
double x = i / 10.;
This will result in a finer x, so it will usually be even closer to i/10. However, it will still usually not be exactly i/10.
If you need exactly i/10, you should explain your requirements further.
NO the cast is not necessary in this case
float x;
x = x + float(0.1);
You can simply write
x+= 0.1