Getting different output for cout and printf while printing same variable - c++

Using Devc++
for printf getting 0.00000
and for cout getting some weird output.
#include<iostream>
#include<cmath>
#include<stdio.h>
using namespace std;
main()
{
float i,j=M_PI;
i=sin(j);
printf("%f \n",i);
cout<<i;
}

It looks to me like M_PI isn't exactly pi (we know it can't be), and the result from sin isn't exactly zero.
printf with %f represents output numbers rounded as a "normal" decimal while cout uses an adaptive format (roughly %g in printf as I recall) that uses scientific notation to represent the small number.
Also note that %f means double but that the varargs helpfully promotes your float to a double when being passed in.

As mentioned you get different output values because the cout one uses scientific notation and the printf defaults to 6 decimal places. If you increase it by using
printf("%.013f \n",i);
You'll get the same value.
Now not all decimal numbers can be represented with floating point representation which is why you don't get the result you are expecting.
Also here's a question on how sin might be implemented on different platform, you can then see why sine of PI might not be 0.

Related

Why are pow(x,1/p) and pow(x,1.0/p) not equal even though printing their values gives the same result

The question is:
You are given 2 numbers (N , M); the task is to find N√M (Nth root of M).
Input:
The first line of input contains an integer T denoting the number of test cases. Then T test cases follow. Each test case contains two space separated integers N and M.
Output:
For each test case, in a new line, print an integer denoting Nth root of M if the root is an integer else print -1.
Now my solution to this problem was:
#include <math.h>
#include <iostream>
#include <math.h>
using namespace std;
int main() {
int t;
float x, p;
cin>>t;
for(int i=0;i<t;i++)
{
cin>>p>>x;
if(p==0)
{
cout<<"1"<<endl;
}
else
{
float res=pow(x,(1/p));
cout<<"res="<<res<<endl;
if(res==int(res))
cout<<res<<endl;
else
cout<<"-1"<<endl;
}
}
return 0;
}
This caused a problem in the test case :
1
3
1000
Although when I printed res, I got 10 as a result, during the condition checking if(res==int(res)) turned out to be false.
Also I noticed that changing from float res=pow(x,(1/p)); to float res=pow(x,(1.0/p)); was giving the correct answer. I'm guessing its something related to getting 0.33333 when the evaluation of 1/p is done, but I cannot understand why the printed value is 10 but not matching in the condition checking.
Why are pow(x,1/p) and pow(x,1.0/p) not equal even though printing their values gives the same result (?)
Computations differ due to precision. Computations are not mathematically exact: pow() did not receive an exact 1/3.
With float p, 1/p can differ from 1.0/p as the first is done using float (or wider) math and the second uses double (or wider) as 1.0 is a double.
This in turn calls either a float or double pow(). Thus there are potentially different res results.
In OP's case: pow(1000.0f,(1/3.0f)) performed a float precision calculation something like pow(1000, near_one_third) and not cbrt(1000.0) - the result was not exactly 10.0f. pow(1000.0f,(1.0/3.0f)) performed a like-wise double precision computation that when rounded to float was exactly 10.0f.
why the printed value is 10 but not matching in the condition checking.
Should res have a computed value a wee more or less than 10.0f, then == is not true.
Print with sufficient precision to see differences in the final output. Recommend at least 9 significant digits for float res.
At a minimum, I suggest using the same floating point types and math throughout. (Use 1.0f with float.) Further recommend to use double.
Final outputs may still not be the exact expected integer (from a math analysis) as pow() though.

C++ print number with decimals

I have a GPS antenna attached to a Raspberry Pi and tried to get its coordinates through C++ with the gps.h library. In there, the latitude is defined as double. Now, when I tried to print it out using printf, with %d the output is 5 and with %f it's 0.000000. I'm just tying to get the exact number that's behind the latitude.
I live in Switzerland and the latitude here is at around 47 degrees. I think that the latitude is stored as 4.7... and there could be some rounding happening, hence the output 5.
Thanks to everybody
edit:
struct gps_data_t gps_d;
printf("%d\n", gps_d.fix.latitude);
I see that gps_d.fix.latitude is a double value, you have to use either %f or %lf to print it using printf. And it also says valid if mode is >=2 so check your code if this is the case. If %f is printing 0.0 then probably the variable value contains actually 0.0.
double latitude; /* Latitude in degrees (valid if mode >= 2) */
However, if you are programming in C++ then you can also print as below:
std::cout << gps_d.fix.latitude << std::endl;
I agree with Jabberwocky. You can try to read the NMEA to check whether the GPS works.
cat /dev/<GPS Serial Port>

Why can't we compare a float value with some numerical value [duplicate]

This question already has answers here:
Is floating point math broken?
(31 answers)
Closed 2 years ago.
I tried the below code i assigned a float value to variable and i compared it with a floating point value but it did not gave the desired output.
Here as a==13.30 is true i thought it will print "a" instead it prints "5"
#include<iostream>
using namespace std;
int main()
{
float a=13.30;
if(a==13.30)
cout<<a;
else
cout<<"5";
}
output is "5" not "a"
13.30 is a double. Try comparing against 13.30f.
0.30 cannot be represented exactly and since double has a higher precision, it is not an exact match.
Ofcourse you can simply compare float value with some numerical value , but just because you can , it doesn't mean you should. It's classical example of that .
There are many problems regarding storing exact floating point value in memory , due to hardware restrictions , this issue regarding storing exact floating point value in memory exist in virtually all the programming languages and platform . A better way to equating floating point values is checking if the difference of two values that you need to compare is less than some other very small number . In your code , you can implement that as ,
#include <iostream>
using namespace std;
const double EPSILON = 1e-5;
int main()
{
float a = 13.30;
if (abs(a - 13.30) < EPSILON)
cout << a;
else
cout << "5";
}
Now , this code will output 13.30 , here EPSILON is used as a very small double value to compare with the difference .
To know more about why this issue is prevalent read , Is-floating-point-math-broken and Why are floating point numbers inaccurate

Double 10 decimal Point Precision

We want to ensure that upto 10 decimal point values are kept while converting a double value to a string.
When we tried %e or %f, it will not keep more than 5 decimal points.
When we tried %.14f, the small values (less than 1.0e-20) are not properly converted to string.
What format string to be used to keep upto 10 decimal points for double values?
Try %.17g to print with the most appropriate format for the double in question.
printf("%.17g\n", 10000.);
printf("%.17g\n", 240.0008);
printf("%.17g\n", 0.0000000013);
10000
240.0008
1.3000000000000001e-009
I hope you do know that the float type (single-precision floating point) only ever keeps six decimal digits of precision? No conversion specifier can give precision that isn't there to begin with... (The double type keeps about 15 digits of precision, FYI.)
Link: http://en.wikipedia.org/wiki/Floating_point#Internal_representation
Update: JasonD has the answer to your updated question. Keeping this up for posteriority.
Float can store this number of decimal only if the number is small, otherwise use double.
In this example %.17g and %.14f are working without problem :
#include <stdio.h>
int main(void)
{
double v = 0.12345678912345;
printf("%.17g %.14f \n", v, v);
return 0;
}
Displayed result :
0.12345678912345 0.12345678912345
From the documentation
f : Decimal floating point, lowercase 392.65
e : Scientific notation (mantissa/exponent), lowercase 3.9265e+2
g : Use the shortest representation: %e or %f 392.65
So using %.14f it is fine
Edit:
the small values (less than 1.0e-20) are not properly converted to string.
To display more than 20 decimal, you should use long double... But if you only need to store 1.0e-20 and do not need to print more than 6 decimal, float can hold it.
For long double, you need to use something like %.21Lg. For example :
#include <stdio.h>
int main(void)
{
long double v = 0.123456789123456789123456789;
printf("%.21Lg %.21Lf \n", v, v);
return 0;
}

Strange rounding of numbers when reading in from text file C++

I have a text line containing only the following lines.
0.01180994648909809 0.0118339243907452 0.01153905217670122
0.0376759911531237 0.03771224865527065 0.03765957194275842
I used the following code to read this data and output it to terminal
using namespace std;
int main(int argc, char *argv[])
{
ifstream infile(argv[1]);
string line;
double a,b,c;
while(getline(infile,line))
{
istringstream iss(line);
iss >> a >> b >> c;
cout<<a<<"\t"<< b << "\t"<<c<<endl;
}
return 0;}
The output I got was
0.0118099 0.0118339 0.0115391
0.037676 0.0377122 0.0376596
Why is it that in the output the numbers have been rounded to 7 digits after the decimal? Is this rounding performed only while displaying to standard output?
EDIT: Moving the proposed solution at top of the relevant information.
You can use set::precision to see the proper precision.
Apart from the answer above, It is important to note that Whenever, You use float and decimal numbers Rounding Errors & Precision are an definite factor.
What is an Precision Error?
The precision of a floating point number is how many digits it can represent without losing any information it contains.
Consider the fraction 1/3. The decimal representation of this number is 0.33333333333333… with 3′s going out to infinity. An infinite length number would require infinite memory to be depicted with exact precision, but float or double data types typically only have 4 or 8 bytes. Thus Floating point & double numbers can only store a certain number of digits, and the rest are bound to get lost. Thus, there is no definite accurate way of representing float or double numbers with numbers that require more precision than the variables can hold.
What is a Rounding Error?
There is a non-obvious differences between binary and decimal (base 10) numbers.
Consider the fraction 1/10. In decimal, this can be easily represented as 0.1, and 0.1 can be thought of as an easily representable number. However, in binary, 0.1 is represented by the infinite sequence: 0.00011001100110011…
An example:
#include <iomanip>
int main()
{
using namespace std;
cout << setprecision(17);
double dValue = 0.1;
cout << dValue << endl;
}
This output is:
0.10000000000000001
And not
0.1.
This is because the double had to truncate the approximation due to it’s limited memory, which results in a number that is not exactly 0.1. Such an scenario is called a Rounding error.
So be aware of these errors when you use floar or double.