C++ print number with decimals - c++

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>

Related

Getting different output for cout and printf while printing same variable

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.

Cannot find second part of if-else loop

Hi guys really need your help. There is some problem with my code and i can't figure out whats the error.T
his is my code:
#include<stdio.h>
void main(void)
{
float timeLeavingTP;
int transitNumber;
float transitTime;
printf("Please enter the time leaving TP.\n");
scanf_s("%f",&timeLeavingTP);
printf("Please enter bus number.\n");
scanf_s("%d",&transitNumber);
if(timeLeavingTP==1.00)
{
if(transitNumber==27)
{
printf("The time reached home is 1.54pm.\n");
}
if(transitNumber==8)
{
printf("The time reached home is 1.39pm.\n");
}
if(transitNumber==15)
{
printf("The time reached home is 1.42pm.\n");
}
}
else if(timeLeavingTP==6.30)
{
if(transitNumber==27)
{
printf("The time reached home is 7.32pm");
}
if(transitNumber==8)
{
printf("The time reached home is 7.29pm");
}
if(transitNumber==15)
{
printf("The time reached home is 7.28pm.\n");
}
}
}
After debugging i got
Please enter time leaving TP
1.00
Please enter bus number
27
The time reached home is 1.54pm
Another debugging
Please enter time leaving TP
6.30
Please enter bus number
27
Please enter any key to continue...
May i ask why did the 1.00 work and why the 6.30 do not work. Need your guys help. Thanks a lot!!
This might help you:
http://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/
You are comparing floating point number for equality which may not work. Also read, the following question:
What is the most effective way for float and double comparison?
This link will also the useful:
http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm
Solution which I suggest in your case is to keep time in integer format (by using 24 hour time format such as 1300 etc) which is in integer and there equality comparison will work.
Also read in C++ FAQs: http://www.parashift.com/c++-faq/floating-point-arith.html
You should avoid using floats for time values like these. A float will only equate a literal, if they are EXACTLY the same. Due to way that a computer stores floating point numbers, they are never exactly what you entered (in this case, it could be stored as 6.30000, which won't be equal to 6.30 to the code).
Since you're not doing anything fancy with the time, I'd suggest reading it in as a string, rather than a float.
try using double instead of float for variables.
double timeLeavingTP;
The values of x and y aren't exactly 0.3 and 0.7, as those numbers aren't representable in binary floating point. It happens that the closest float to 0.3 is greater than the closest double to 0.3, and the closest float to 0.7 is less than the closest double to 0.7... hence your comparison results.
Assuming the representations are the same as in C# (where I happen to have some tools to help) the values involved are:
0.3 as float = 0.300000011920928955078125
0.3 as double = 0.299999999999999988897769753748434595763683319091796875
0.7 as float = 0.699999988079071044921875
0.7 as double = 0.6999999999999999555910790149937383830547332763671875
So that explains why it's happening... but it doesn't explain how to work around the issue for whatever your code is actually trying to do, of course. If you can give more context to the bigger problem, we may be able to help more.
When comparing float to constant you should use extension f
like this:
else if(timeLeavingTP==6.30f)
You really shouldn't use a float for time value. 6.30 is 6:30 or 6:18? what will happen if we add 1.40 to 6.30?
Ok, already a lot of answers. Some additional information:
In C++ standard, section 2.14.14, it is stated that:
The type of a floating literal is double unless explicitly specified by a suffix.
This means that you compare your float variable with a double constant. Unfortunately floating point conversion (float and double) can give very small differences. But the difference is smaller for double which are more precise than for float. This is why your float doesn't match the double.
To avoid this, either use two doubles (see a lot of other responses above), or use two floats, by changing your else if to:
else if (timeLeavingTP == 6.30f)
6.30 looks like a nice simple floating-point number, and in decimal it is, but in binary floating point it is not. 6.30 cannot be represented by a float, and it cannot be represented by a double. It cannot be perfectly represented by any binary floating-point number.
When you write this statement (after assigning 6.30 to timeLeavingTP):
if(timeLeavingTP==6.30)
what you are actually doing is this:
if((float)6.30==(double)6.30)
You are comparing the 32-bit float representation of 6.30 to the 64-bit double representation of 6.30. Both are approximations. The double representation is a closer approximation. Therefore they are not equal.
You could add an epsilon to allow for this slop, but better solutions would be to use 6.30f as your constant (make the right side also a float) or make timeLeavingTP a double. The goal is not to get greater accuracy, but to have consistent accuracy.
See this article for details on this exact problem:
http://randomascii.wordpress.com/2012/06/26/doubles-are-not-floats-so-dont-compare-them/
try this:
#include<stdio.h>
void main(void)
{
float timeLeavingTP;
int transitNumber;
float transitTime;
printf("Please enter the time leaving TP.\n");
scanf_s("%f",&timeLeavingTP);
printf("Please enter bus number.\n");
scanf_s("%d",&transitNumber);
if(timeLeavingTP==1.00)
{
if(transitNumber==27)
{
printf("The time reached home is 1.54pm.\n");
}
if(transitNumber==8)
{
printf("The time reached home is 1.39pm.\n");
}
if(transitNumber==15)
{
printf("The time reached home is 1.42pm.\n");
}
}
if(timeLeavingTP==6.30)
{
if(transitNumber==27)
{
printf("The time reached home is 7.32pm");
}
if(transitNumber==8)
{
printf("The time reached home is 7.29pm");
}
if(transitNumber==15)
{
printf("The time reached home is 7.28pm.\n");
}
}
}

C++ printf printing doubles reads as 0

So I want to use printf so that I can make columns line up but printf can't seem to print doubles that need scientific notation. It just comes out as a 0 but with cout it comes out fine. 'in' and 'fn' are structs 'x' 'y' and 'z' are doubles
Code
printf("Facet Normal: %lf %15lf %15lf\n", in->fn.x, in->fn.y, in->fn.z);
cout << "cout test: " << in->fn.x << endl;
Output
Facet Normal: -0.000000 -0.894426 0.447215
cout test: -9.6137e-08
I can't seem to get printf to work correctly. I had the entire function working correctly with cout but like I said, I'd like things to line up niftily.
Edit:
As Oli said, using %e does get it to print correctly. By using %e throughout though it puts everything in scientific notation and a lot of the numbers in the data set don't in reality really need it. Cout seems to convert between %lf and %e as needed. Is there an easy way to get printf to get this behavior as well?
Answer:
%f is for both float and double (since float arguments are promoted to double);
%lf is for long double. f prints with no exponent, e prints with an exponent, and
g uses whichever looks better (following specific rules).
– Keith Thompson
%g gets the exact behavior I was looking for!
As the std::printf() reference says, just use %e:
std::printf( "One double in decimal scientific notation! %e" , my_double );
But the correct C++ way is to use std::cout and some manipulators, std::scientific in this case:
std::cout << "One double in decimal scientific notation!" << std::scientific << my_double;
Note that the format of std::cout forms part of its state, that is, you only have to configure it once, the format is applied to any output operation after the setting, and before other format change:
std::cout << std::scientific;
std::cout << std::pow( 10.0 , 10.0 ) << std::endl;
std::cout << std::pow( 10.0 , 20.0 ) << std::endl;
std::cout << std::pow( 10.0 , 30.0 ) << std::endl;
1e11
1e21
1e31
It seems you want to get the "best" formatting (which is the default for std::ostream): you can use %g (%Lg for long double) to have the formatting function decide how the values should be formatted. There are four format specifiers:
%f for fixed point notation (the format used by std::fixed for streams).
%e for scientific formatting (the format used by std::scientific for streams).
%g for the "best" version of fixed and scientific (the default for streams and since C++11 std::defaultfloat).
%a for an exact/hex representation of the floating point number (since C++11 std::hexfloat).
The formatting flags can used both in lowercase and uppercase to indicate whether any characters should be lowercase or uppercase (e.g. e vs. E). Note that the l length specifier is actually not relevant for the floating point formatting. You might need to use L, though, when formatting long double
If you want to control the output from std::cout, use setw() and setfill().
http://www.cplusplus.com/reference/iomanip/setw/
You can also set the precision, etc. I will leave that to you to explore.

Floats and scientific notation

I am creating 1D and 2D array from a file that contains lines that look like this:
42857000 -923070 0 0 -7887
428570 -546190 -4285700 546190 0
-6.5 -0.15384 6.5 0.15384 0.007
0 0 42857000 360570 0
When I populate the arrays from the file, they get converted to scientific notation:
42857000 >>>>> 4.2857000e+007 etc!!!
Is there anyway to stop this?
My arrays are defined as follows:
float aMatrix[DEFROWS][DEFCOLS] = {0.0};
float bMatrix[DEFCOLS] = {0.0};
This issue is causing my app to crash.
Thanks.
I assume this is just from printing with cout. If that's the case, use std::fixed:
std::cout << std::fixed << whateverNumberCurrentlyInScientific;
Is it crashing on reading it in or sending it out? Are you using cout or printf? One extremely common way to crash it to use printf with a %d and send it a floating point value.

WxWidgets: Simple math formula hands wrong results?

I am greatly liking WxWidgets, and started with C++ programming in it. My sample program converts Celsius into Fahrenheit from a text form. Here is my basic code:
//get "100" from textbox
wxString szCelsius = TextCtrl1->GetValue();
long lCelsius;
//attempt to cast into long
szCelsius.ToLong(&lCelsius, 10);
//formula that works in normal cases to get fahrenheit
long lFahrenheit = ((9.f/5.f) * lCelsius + 32);
//SOMEHOW this works:
//long lFahrenheit = ((9.f/5.f) * 100 + 32);
//display debug info, note it displays lCelsius as 100
wxString debuginfo;
debuginfo << _T("deg C: ") << lCelsius << _T("\n");
//displays incorrectly as 211
debuginfo << _T("deg F: ") << lFahrenheit << _T("\n");
//this displays 100
std::cout << lCelsius;
//this fails though
assert(lCelsius == 100);
Now with the debug info, lCelcius is 100 like expected but it returns fahrenheit as 211 instead of 212! The odd thing is that formula works fine in pure C, and when I replace lCelsius with 100, it works fine, even though my debug info clearly says it is 100.
Do you see any obvious problem or am I just not able to do such a simple thing? I am not sure quite what Wx is doing to make it one less than it should.
EDIT: including assert.h and running lCelsius == 100 fails in debugger, but std::cout lCelsius returns 100. There must be something up with Wx that is mangling the result but still is "100"..
The value 1.8 (which is 9/5) cannot be exactly represented as a binary floating point number - in binary, it is an recurring series of digits (1.1100110011001100110011001100...) - similar to the way 1/3 is recurring in decimal.
The closest representation as a single-precision floating point value is just under 1.8 - it's approximately 1.7999999523). When this number is multiplied by 100, it results in a value just under 180; and when 32 is then added, it results in a number just under 212.
Converting a floating point number to an integer truncates the decimal portion, so 211.999... becomes 211.
The reason it doesn't happen if you use a literal 100 in the source code, instead of a runtime-supplied value, is because the compiler simplified the expression (9.f/5.f) * 100 at compile time down to a plain 180.
If your compiler supports the C99 roundf() function (declared in math.h), you can use that to round to the nearest integer:
long lFahrenheit = roundf((9.f/5.f) * lCelsius + 32);
You could try debugging this at the assembly level, to see in more detail what is going on.
Also, just as a stylistic suggestion, the leading term could be written as (9.f / 5.f) which gets rid of the casts and is easier to read.
I also question why you use long for the temperature, to me it feels as if most temperatures (especially involving Fahrenheit) are in the range supported by plain int.