I am trying to get the fixed points for the tent equation. With the given initial conditions, the solution must be 0.6. Everything works fine when I use float for x0, but when I define x0 as a double, the solution changes to 0.59999 in 55th iteration, which causes further changes in the next iteration and so on. Why is there such a difference while choosing the data types?
using namespace std;
#include <iostream>
main()
{
double x0=.6;
for (int i=0;i<100;i++)
{
if(x0<.5)
x0=1.5*x0;
else
x0=1.5*(1-x0);
cout << i << "\t" << x0 << endl;
}
}
I have posted an image of the results. Comparison of solutions - Float and Double
The real value of the 55-th iteration is 0.5999994832150543633275674437754787504673004150390625 when a double is used and 0.60000002384185791015625 for a float (on my system).
The difference between the two is in how precise the numbers are and the rounding is what throws you off.
BTW, neither of the two values is absolutely accurate, they are just close enough approximations and nothing more. With the double being "more precise".
UPDATE
After a few comments back and forth it turned out that there was no need for floating-point arithmetic to be gin with. Integers (slightly modified) do just fine and do not introduce any rounding.
Related
Using the GSL (GNU Scientific Library), I'm trying to understand why gsl_vector_view_array() returns a slighly modified value after assignment.
In the code below, I declare a vector_view 'qview_test' which is linked to table q_test[0]=0.0 and display its value which is 0.0. Then, I change the value of q_test[0]=1.12348 and expecting the same value for qview_test, but it gets alterated to qview_test=1.1234800000000000341771055900608189.
How do you explain such a result ? How to replicate the result without GSL ?
#include <iostream>
#include <gsl/gsl_blas.h>
using namespace std;
double q_test[1]={0.0};
gsl_vector_view qview_test;
int nb_variable = 1;
int main()
{
qview_test=gsl_vector_view_array(q_test,nb_variable);
cout.precision(35);
cout << "qview before: " << gsl_vector_get(&qview_test.vector,0)<< endl;
// Assign value
q_test[0]=1.12348;
cout << "qview after: " << gsl_vector_get(&qview_test.vector,0) << endl;
return 0;
}
Thanks for any help,
H.Nam
This looks like floating point rounding to me.
Basically any decimal number can only have a finite precision and all numbers in between get rounded to the nearest float.
I am not familiar with gsl so I don't know why it's displaying so many digits.
In other words, to get more precise give your number more bits (128 bit float or something like that) to be represented. This will give you more precision, however you most likely won't need it.
I made a code to find the derivative of a function at a given point. The code reads
#include"stdafx.h"
#include<iostream>
using namespace std;
double function(double x) {
return (3 * x * x);
}
int main() {
double x, y, dy, dx;
cin >> x;
y = function(x);
dx = 0.00000001;
dy = function(x + dx) - y;
cout << "Derivative of function at x = " << x << " is " << (double)dy / dx;
cin >> x;
}
Now my college uses turbo C++ as its IDE and compiler while at home I have visual studio (because TC++ looks very bad on a 900p screen but jokes apart). When I tried a similar program on the college PCs the result was quite messed up and was much less accurate than what I am getting at home. for example:
Examples:
x = 3
#College result = 18.something
#Home result = 18 (precise without a decimal point)
x = 1
#College result = 6.000.....something
#Home result = 6 (precise without a decimal point)
The Very big Question:
Why are different compilers giving different results ?
I’m 90% sure the result’s same in both cases, and the only reason why you see difference is different output formatting.
For 64-bit IEEE double math, the precise results of those computations are probably 17.9999997129698385833762586116790771484375 and 6.0000000079440951594733633100986480712890625, respectively.
If you want to verify that hypothesis, you can print you double values this way:
void printDoubleAsHex( double val )
{
const uint64_t* p = (const uint64_t*)( &val );
printf( "%" PRIx64 "\n", *p );
}
And verify you have same output in both compilers.
However, there’s also 10% chance that indeed your two compilers compiled your code in a way that the result is different. Ain’t uncommon, it can even happen with the same compiler but different settings/flags/options.
The most likely reason is different instruction sets. By default, many modern compilers generate SSE instructions for the code like yours, older ones producer legacy x87 code (x87 operates on 80-bit floating point values on the stack, SSE on 32 or 64-bit FP values on these vector registers, hence the difference in precision). Another reason is different rounding modes. Another one is compiler specific optimizations, such as /fp in Visual C++.
#include <iostream>
#include <iomanip>
#include <math.h>
using namespace std;
int main() {
int t;
double n;
cin>>t;
while(t--)
{
cin>>n;
double x;
for(int i=1;i<=10000;i++)
{
x=n*i;
if(x==ceilf(x))
{
cout<<i<<endl;
break;
}
}
}
return 0;
}
For I/P:
3
5
2.98
3.16
O/P:
1
If my code is:
#include <iostream>
#include <iomanip>
#include <math.h>
using namespace std;
int main() {
int t;
double n;
cin>>t;
while(t--)
{
cin>>n;
double x;
for(int i=1;i<=10000;i++)
{
x=n*i;
cout<<"";//only this statement is added;
if(x==ceilf(x))
{
cout<<i<<endl;
break;
}
}
}
return 0;
}
For the same input O/P is:
1
50
25
The only extra line added in 2nd code is: cout<<"";
Can anyone please help in finding why there is such a difference in output just because of the cout statement added in the 2nd code?
Well this is a veritable Heisenbug. I've tried to strip your code down to a minimal replicating example, and ended up with this (http://ideone.com/mFgs0S):
#include <iostream>
#include <math.h>
using namespace std;
int main()
{
float n;
cin >> n; // this input is needed to reproduce, but the value doesn't matter
n = 2.98; // overwrite the input value
cout << ""; // comment this out => y = z = 149
float x = n * 50; // 149
float y = ceilf(x); // 150
cout << ""; // comment this out => y = z = 150
float z = ceilf(x); // 149
cout << "x:" << x << " y:" << y << " z:" << z << endl;
}
The behaviour of ceilf appears to depend on the particular sequence of iostream operations that occur around it. Unfortunately I don't have the means to debug in any more detail at the moment, but maybe this will help someone else to figure out what's going on. Regardless, it seems almost certain that it's a bug in gcc-4.9.2 and gcc-5.1. (You can check on ideone that you don't get this behaviour in gcc-4.3.2.)
You're probably getting an issue with floating point representations - which is to say that computers cannot perfectly represent all fractions. So while you see 50, the result is probably something closer to 50.00000000001. This is a pretty common problem you'll run across when dealing with doubles and floats.
A common way to deal with it is to define a very small constant (in mathematical terms this is Epsilon, a number which is simply "small enough")
const double EPSILON = 0.000000001;
And then your comparison will change from
if (x==ceilf(x))
to something like
double difference = fabs(x - ceilf(x));
if (difference < EPSILON)
This will smooth out those tiny inaccuracies in your doubles.
"Comparing for equality
Floating point math is not exact. Simple values like 0.2 cannot be precisely represented using binary floating point numbers, and the limited precision of floating point numbers means that slight changes in the order of operations can change the result. Different compilers and CPU architectures store temporary results at different precisions, so results will differ depending on the details of your environment. If you do a calculation and then compare the results against some expected value it is highly unlikely that you will get exactly the result you intended.
In other words, if you do a calculation and then do this comparison:
if (result == expectedResult)
then it is unlikely that the comparison will be true. If the comparison is true then it is probably unstable – tiny changes in the input values, compiler, or CPU may change the result and make the comparison be false."
From http://www.cygnus-software.com/papers/comparingfloats/Comparing%20floating%20point%20numbers.htm
Hope this answers your question.
Also you had a problem with
if(x==ceilf(x))
ceilf() returns a float value and x you have declared as a double.
Refer to problems in floating point comparison as to why that wont work.
change x to float and the program runs fine,
I made a plain try on my laptop and even online compilers.
g++ (4.9.2-10) gave the desired output (3 outputs), along with online compiler at geeksforgeeks.org. However, ideone, codechef did not gave the right output.
All I can infer is that online compilers name their compiler as "C++(gcc)" and give wrong output. While, geeksforgeeks.org, which names the compiler as "C++" runs perfectly, along with g++ (as tested on Linux).
So, we could arrive at a hypothesis that they use gcc to compile C++ code as a method suggested at this link. :)
#include <iostream>
using namespace std;
int main()
{
cout.precision(32);
float val = 268433072;
float add = 13.5;
cout << "result =" << (val + add) << endl;
}
I'm compiling the above program with standard g++ main.cc
and running it with ./a.out
The ouput I receive however, is,
result =268433088
Clearly, this is not the correct answer..Why is this happening?
EDIT: This does not occur when using double in place of float
You can reproduce your "float bug" with an even simpler piece of code
#include <iostream>
using namespace std;
int main()
{
cout.precision(32);
float val = 2684330722;
cout << "result =" << val << endl;
}
The output
result =2684330752
As you can see the output does not match the value val was initialized with.
As it has been stated many times, floating-point types have limited precision. Your code sample simply exceeded that precision, so the result got rounded. There's no "bug" here.
Aside from the reference to (1991, PDF) What Every Computer Scientist Should Know About Floating-Point Arithmetic
The short answer is, that because float has limited storage (like the other primitives too) the engineers had to make a choice: which numbers to store with which precision. For the floating point formats they decided to store numbers of small magnitude precisely (some decimal digits), but numbers of large magnitude very imprecisely, in fact starting with +-16,777,217 the representable numbers are becoming so thin that not even all integers are represented which is the thing you noticed.
Actually I am working on range expression in c++. So what I want is if I have any expression like
x<1
Then my
double getMax(...);
should return a double value that is just before 1.000 (double precision) on a number line.
I tried doing this
double getMax(double& a)
{
return (a-numeric_limits<double>::min());
}
But I am still getting same value as a in return statement.
I think C++ is converting it to nearest double in cout statement.
int main()
{
double a = 32;
cout<<scientific<<getMax(a)<<endl;
return 0;
}
output:
3.200000e+001
First of all, you need to ensure that you actually print sufficiently many digits to ensure all representable values of double are displayed. You can do this as follows (make sure you #include <iomanip> for this):
std::cout << std::scientific << std::setprecision(std::numeric_limits<double>::max_digits10) << getMax(a) << std::endl;
Secondly, numeric_limits<>::min is not appropriate for this. If your starting value is 1.0, you can use numeric_limits<double>::epsilon, which is the smallest difference from 1.0 that is representable.
However, in your code example, the starting value is 32. Epsilon does not necessarily work for that. Calculating the right epsilon in this case is difficult.
However, if you can use C++11(*), there is a function in the cmath header that does what you need std::nextafter:
#include <iostream>
#include <limits>
#include <iomanip>
#include <cmath>
double getMax(double a)
{
return std::nextafter(a,std::numeric_limits<double>::lowest());
}
int main()
{
double a = 32;
std::cout << std::scientific
<< std::setprecision(std::numeric_limits<double>::max_digits10)
<< getMax(a)
<< std::endl;
return 0;
}
I've also put it on liveworkspace.
To explain:
double nextafter(double from, double to);
returns the next representable value of from in the direction of to. So I specified std::numeric_limits<double>::lowest() in my call to ensure you get the next representable value less than the argument.
(*)See Tony D's comment below. You may have access to nextafter() without C++11.
I think you've got the right idea.
Check out Setting the precision of a double without using stream (ios_base::precision) not so much for the question, but for the examples they give of using precision. You might want to try something like printing with a precision of 53.
The way I usually see "close to but not quite" involves setting a difference threshold (typically called epsilon). In that case, you wouldn't use a getMax function, but have an epsilon used in your usage of less than. (You could do a class with the epsilon value and operator overloading. I tend to avoid operator overloading like a plague.)
Basically, you'd need:
bool lessThanEpsilon(double number, double lessThan, double epsilon)
{
return (lessThan - number >= epsilon);
}
There are other varieties, of course. Equals would check if Math.abs(number - equals) < epsilon