Floats and scientific notation - c++

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.

Related

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>

C++ Write a long float number to a file

file.txt
123.56
89.78
8.89
468.98
567.90
5.78
178908.90
12.56
6789.90
12.56
16.780
0.00
I've parsed the numbers into an array called float A[150] = {0}.
So, A looks like:
A[0] = 123.56
A[1] = 89.78
....
....
A[10] = 16.780
A[11] = 0.00
A[12] = 0
A[13] = 0
...
...
Then, I have a sorting Algorithm
Sort(A, i) // where i is the number of elements (12)
Now A[] looks like
A[0] = 0
A[1] = 5.78
...
...
A[10] = 6789.90
A[11] = 178908.90
Then, I write it to a file called "Final.txt"
std::ofstream File (Name);
if (File.is_open())
{
for (j = 0; j < i; j++)
{
File << A[j] << std::endl;
}
}
The file output "Final.txt" looks like:
0
5.78
8.89
12.56
12.56
16.78
89.78
123.56
468.98
567.9
6789.9
178909 // Why it is NOT CORRECT !!!!!!!
The problem with A[11] after the sorting, why is it not correct in "Final.txt", even though it is correct when I debug it in the A[11] ?
Floating point values are printed with several constraints to make the values readable. For instance you would probably not want the output of
16.78 to read
16.799999999999998
Which might well be a more correct representation of 16.78. To avoid that operator << operation on ostreams uses a precision field to determine how many significant digits to print. This value is obviously set too small for your application.
Reference http://en.cppreference.com/w/cpp/io/manip/setprecision.
Other formatting settings is given by the link πάντα ῥεῖ provided.
You have different problems when trying to output 178908.90
First, the default implementation of c++ ostream normally outputs 178909, because as explained by Captain Giraffe, the default format does its best to avoid irrelevant digits and precision
You could try to force a fixed floating point with 2 digits in precision but then you will get 178908.91 (if you use float and not double). Because you would fall in second problem : in C++, floating point numbers (float or double) use IEEE-754 format which offers only about 7 decimal digits in precision, and internally it is more like : 178908.906
So the rule is : if you want to keep roughly the input precision, do not use numbers of more than 6 decimal digits for float and 14 for double, and if you want to keep strictly input precision, do not use floating point at all !
You can try to use decimal types as shown in that other answer, or build your own class.

Round decimal for a float number

in VC++ I have a float number say 1.32544354353
i.e float num=1.32544354353;
I want only first 1 digit after point. i.e 1.3 (not 1.300000000).
How can I get this?
Please help me...
If their is a solution in Cocos2dx thats better(I want this in my cocos2d-x game)
The answer depends on what type do you want the result to be.
If you want to obtain the result as float, then this is impossible. From float's point of view, 1.3 and 1.300000000 are exactly the same values and you can not have a float that holds 1.3, not 1.300000000. What you can do here is to drop extra digits by using, e.g., (int)(val*10)/10.0. (However, the float number precision problems will not make the results exactly 1.3, it will be something line 1.2999999982 or 1.3000000029 with some random digits at the end.)
If you want a string (meaning a string in general) representation, then you can gen a string "1.3". To obtain this, use precision specifiers
such as "%.1f" or std::setprecision(1).
Try something like
float val=1.32544;
float num=(float)(((int)(val*10))/10.0);
but beware of the overflow.
Try this:
#include <math.h>
float x= 1.32544354353;
float f = roundf(x* 10) / 10;
If you just want to print it then you can simply use the format specifier like this:
("%.1f", 1.32544354353);
or
double d = 1.32544354353;
std::cout << std::fixed << std::setprecision(1) << d << std::endl;
first thing that comes in my mind is that you can multiplay this by 10 (you will get 13) then cast this to int (so no more numbers after dot) and then divide this by 10 to float (you will get 1.3)
char str[50];
sprintf(str, "%.1f",1.324567);
now str have a string 1.3

C - Printing out float values

I have a C++ program that takes in values and prints out values like this:
getline(in,number);
cout << setw(10) << number << endl;
I have an equivalent C program that takes in values and prints out like so:
fscanf(rhs, "%e", &number);
printf("%lf\n", number);
But while the C++ program prints out, 0.30951 the C program prints out 0.309510. More examples: C++: 0.0956439 C: 0.095644. It seems to print the same results as long as the value is 7 digits long, but if its shorter the 7 digits, it adds an extra 0 at the end. And if its longer than 7 digits, it rounds down to 6 digits. I would like the C results to match the C++ program. Any help would be appreciated.
Thanks.
Note: number is a float and number are read from a file.
Take advantage of the length and precision specifiers in C++ iostreams
std::cout.precision(4);
std::cout << std::setw(10) << number << "\n";
Take advantage of the length and precision specifiers in C formatted print statements:
printf( "%6.4lf", number );
Prints four decimal places in a "cell" six characters wide.
You can use a wildcard character for either length or precision to provide that value at runtime:
int precision = 4;
printf( "%6.*lf", precision, number );
printf("%g\n", number);
Will solve your problem, %lf is used for double, %f is used for float, and %g is used for float when you want to display all the decimal places and cut off zeros.

C++ checking floats

Right, I have an array for floats which stores only 1s and 0s. I'm trying to just do a simply test/check that the current slot in the array is 1 it will print out a little message to say it is 1, otherwise, it is 0. Heres my code:
if(myArray[i] == 1)
{
cout << "this is 1 !!!!!" << endl;
}
else
{
cout << "this is 0 ";
}
but this just keeps entering the "else" section. i.e. only printing "this is 0". Whats wrong with it (or whats wrong with me?? :P)??
Great link: What Every Computer Scientist Should Know About Floating-Point Arithmetic
After reading that you'll realise that the floating-point representation of 1 isn't quite the integer value 1. It's close, but not quite, and that's why your condition will always be false.
Why would you use floats to store boolean data? Use an array of bools or a bitvector.
EDIT: I can't actually think of any situation where (or why) you'd compare floats to a literal, anyone know any?
When operating with floating point numbers you should program a little more defensive:
if (myArray[i] == 1) {
cout << "this is 1\n";
} else if (myArray[i] == 0) {
cout << "this is 0\n";
} else {
cout << "this is something else, in particular " << myArray[i] << "\n";
}
This should give you an insight about what happens.
By the way, if you only ever store the values 1.0f and 0.0f in the array, it is perfectly ok to use the == operator to compare floats. You just have to be sure that what you think is 1.0 is really really really 1.0.
First, don't use floats to store a 1 or a 0. There is no reason to use a float to store small integers.
Second, you need to read into What Every Computer Scientist Should Know About Floating Point Numbers. Though it will often work, you should compare floating point values by taking the absolute value of the difference between them and comparing that with some small sigma (where sigma is a value that makes sense in your application within the valid range of precision).
If abs( x - y ) < sigma you can consider them equal.
Depending on how you arrived at the values in your array (i.e. the result of computations), it's highly unlikely that you'll get an exact 0 or 1 as a floating point result. Checking if a float == 1 exactly will almost certainly be false in that case.
On the other hand, in IEEE floating point, an exact 0 is stored as 0x00000000. If it's not the result of a computation, sticking a 0 in your array can be useful as a flag instead of storing a separate array.
There could be very good reason that the value in your floating point array is off by very slight fraction to be equal to 1.
Though this is not a clean solution, this should be reason enough to use either enum or a bool array.
if(myArray[i] > 0.9f && myArray[i] < 1.00001f)
...
...
I've answered something about this
here. You can't do a "==" to compare float and int.
In your case, maybe the float 1 is actually 0.9999999 which will be truncated to 0, which is the output of your program is already correct.
Either cast the array element to an int:
if ((int)myArray[i] == 1)
Or cast the 1 to a float:
if (myArray[i] == 1.0f)