Reputation: 3434
In my below program,
main
{
// value is 476
int value = 476;
// here dimension shows as 0.100000001
float dimension = 0.1f;
/// Here I am expecting value as 47.6,
/// But it gives value as 47.600002288818......
double result = value * dimension;
}
I want to save the value directly in database, So is there any inbuild function to get the expected value ?
Expected : 47.6 instead of 47.600002288.....
Upvotes: 0
Views: 458
Reputation: 924
the value is stored 47.600002288
for precision, but when you want to use it you can use just N digits after the floating point, for example if the value is (47.600002288) in printf
use:
printf("%.2f\n", result);
this will print 47.60
, notice the .2
after %
it tell the formatting function to print 2 number after the floating point.
Note that you can print it directly to a string using sprintf
:
char s= malloc(sizeof(char)*10);
sprintf(s, "%.2f\n", result);
//s contains "47.60"
In this case you have to be aware of the malloc
parameter i used sizeof(char)*10
this means that the character length must be under or equal 9 (cause the last character is reserved for string ending char \0
).
Upvotes: -1
Reputation: 36617
Floating point is, in practice, has a mantissa represented in binary (base 2). One consequence of this is that 0.1
decimal (aka the fraction 1/10
) cannot be exactly represented in floating point.
The reason is the same as 1/3
cannot be represented exactly in a fixed number of decimal places - it is an infinitely recurring value 0.3333333.....
, and truncating it to a finite number of places introduces an error. The only difference is that 1/10
is a infinitely recurring value in base 2. So it cannot be represented exactly in a finite number of binary digits.
There are obviously other values affected in such a way (such as 0.2
, 0.6
, etc). Such errors are an inherent property of floating point representations .... or, to put it another way, floating point represents an approximation (the value with a potential lack of precision). And, when doing a sequence of calculations, the errors in the values propagate.
Since there is no way to exactly represent the value 0.1
in floating point (and other values), there is no way to exactly store a floating point value into a database and get a value that is exactly 0.1
.
You can try printing the value in a way that limits the precision of output, such as
#include <sstream>
#include <iomanip>
#include <string>
std::ostringstream o;
o << std::fixed << std::setprecision(2) << result;
std::string s=o.str();
Bear in mind this controls how result
is formatted (e.g. on output to a string in this case). It does not change the value of result
.
Notionally, the string s
can be stored in your database .... if the field represents a string rather than a numeric value.
Upvotes: 0
Reputation: 118445
There are a few ways, but in all cases you will have to figure out and decide how many digits of precision your floating point values should represent. There's nothing about a float
that says "I'm actually .1 instead of 0.100000001".
Once you decided on, say, that your values should carry two digits of precision, there are a few ways to round them off. One simple way is to use stream formatting:
#include <sstream>
#include <iomanip>
std::ostringstream o;
o << std::setiosflags(std::ios::fixed) << std::setprecision(2) << 0.1;
std::string s=o.str();
You will now find "0.10" in s
.
If you do not know how many digits of precisions are significant as a result of whatever calculations you're doing, your only option is to use a dedicated library for fixed precision arithmetic, like GMP.
Upvotes: 3