C++ is not my language so forgive this simple problem. I'm losing precision in an atof conversion from string to double, can anyone help?
string lAmount;
string lSuspendedInt = "131663.51";
string lAccruedInterest = "0.0";
double dSuspendedInt= atof(lSuspendedInt.c_str()); //PROBLEM HERE?
double dAccruedInterest = atof(lAccruedInterest.c_str());
double dTotal = dSuspendedInt + dAccruedInterest;
char cAmount[50];
memset(cAmount,0X00,sizeof(cAmount));
sprintf(cAmount,"%g*",dTotal);
lAmount = cAmount;
cout << "lAmount: "<<lAmount<<endl; //PRINTING: 131664 not 131663.51
I've played with %f in the memset function however this gives 131663.510000
Thanks in advance.
Sapatos
The problem is your %g format operator, which isn't specified with enough precision. You might want %.2f instead, which prints two digits after the decimal point.
The sprintf %g format specifier defaults to printing six significant digits. If you want more, you can explicitly specify how many should be printed:
sprintf(cAmount,"%.8g*",dTotal);
The function atof creates a double. See here. Your problem is that the %g returns either the shorter of float or scientific notation. See here. Also note, that you're adding the in * notation which signifies that there is an expected truncation in the number of printed characters.
Related
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;
}
I have some decimal numbers in a text file represented in exponential form Eg: 144.2e-3. I want to store the values in float. In qt it returns "0" when i directly use the "number.toFloat()" method. Please help.
toFloat() should work. Check that your string contains only the number. If the string contains something else too, for example "144.2e-3 a", then the toFloat() returns 0. Note that also other numbers in the string will cause the conversion to fail, for example QString("144.2e-3 100").toFloat() will return 0.
Additional whitespace in the number string doesn't matter, but other characters do.
value = 3.91e+01;
double doubleValue;
stringstream valuestream(value);
valuestream >> doubleValue;
Using a stringstream you can convert exponential number to the datatype we require.
Use QString::toDouble.
Example:
bool ok;
float f = static_cast< float>( QString( "1234.56e-02" ).toDouble( &ok));
I have a double variable in C++ and want to print it out to the screen as a fixed decimal point number.
Basically I want to know how to write a function that takes a double and a number of decimal places and prints out the number to that number of decimal places, zero padding if necessary.
For example:
convert(1.235, 2)
would print out
1.24
and
convert(1, 3)
would print out
1.000
so the function works as
convert(number as double, number of decimal places)
and simply prints out the required value to standard output (cout).
Does anyone know how to do this?
Thanks in advance.
Assuming I'm remembering my format strings correctly,
printf("%.*f", (int)precision, (double)number);
Look at the setprecision manipulator which should give you the idea
There is no such thing as a "fixed decimal place" number. The convert function will need to be the function that actually prints it out. I would suggest getting the whole part of the number, then print it. If [decimal places]>0 then print a decimal place, then print each decimal individually like: floor((n*log(10,d))%10); <-- just an idea, not actual code.
#include <iomanip>
#include <iostream.h>
// print a float, x places of precision
void convert (double number, int x)
{
cout << setprecision(x) << number << endl;
}
int main()
{
double a = 1.234;
convert (a,2);
}
output: 1.23
reference
I was wondering, how long in number of characters would the longest a double printed using fprintf be? My guess is wrong.
Thanks in advance.
Twelve would be a bit of an underestimate. On my machine, the following results in a 317 character long string:
#include <limits>
#include <cstdio>
#include <cstring>
int main()
{
double d = -std::numeric_limits<double>::max();
char str[2048] = "";
std::sprintf(str, "%f", d);
std::size_t length = std::strlen(str);
}
Using %e results in a 14 character long string.
Who knows. The Standard doesn't say how many digits of precision a double provides other than saying it (3.9.1.8) "provides at least as much precision as float," so you don't really know how many characters you'll need to sprintf an arbitrary value. Even if you did know how many digits your implementation provided, there's still the question of exponential formatting, etc.
But there's a MUCH bigger question here. Why the heck would you care? I'm guessing it's because you're trying to write something like this:
double d = ...;
int MAGIC_NUMBER = ...;
char buffer[MAGIC_NUMBER];
sprintf(buffer, "%f", d);
This is a bad way to do this, precisely because you don't know how big MAGIC_NUMBER should be. You can pick something that should be big enough, like 14 or 128k, but then the number you picked is arbitrary, not based on anything but a guess that it will be big enough. Numbers like MAGIC_NUMBER are, not suprisingly, called Magic Numbers. Stay away from them. They will make you cry one day.
Instead, there's a lot of ways to do this string formatting without having to care about buffer sizes, digits of precision, etc, that let you just get on with the buisness of programming. Streams is one:
#include <sstream>
double d = ...;
stringstream ss;
ss << d;
string s = ss.str();
cout << s;
...Boost.Format is another:
#include <boost\format\format.hpp>
double d = ... ;
string s = (boost::format("%1%") % d).str();
cout << s;
Its defined in limits:
std::cout << std::numeric_limits<double>::digits << "\n";
std::cout << std::numeric_limits<double>::digits10 << "\n";
Definition:
digits: number of digits (in radix base) in the mantissa
Equivalent to FLT_MANT_DIG, DBL_MANT_DIG or LDBL_MANT_DIG.
digits10: Number of digits (in decimal base) that can be represented without change.
Equivalent to FLT_DIG, DBL_DIG or LDBL_DIG for floating types.
See: http://www.cplusplus.com/reference/std/limits/numeric_limits/
Of course when you print stuff to a stream you can use the stream manipulators to limit the size of the output.
you can decide it by yourself..
double a=1.1111111111111111111111111111111111111111111111111;
printf("%1.15lf\n", a);
return 0;
./a.out
1.111111111111111
you can print more than 12 characters..
If your machine uses IEEE754 doubles (which is fairly widespread now), then the binary precision is 53 bits; The decimal equivalent is approximately 15.95 (calculated via logarithmic conversion), so you can usually rely on 15 decimal digits of precision.
Consult Double precision floating-point format for a brief discussion.
For a much more in-depth study, the canonical paper is What Every Computer Scientist Should Know About Floating-Point Arithmetic. It gets cited here whenever binary floating point discussions pop up, and is worth a weekend of careful reading.
Lets consider we have a double R = 99.999999; (which may be obtained by a result of some other computation),now the desired output is 99.99
I tried using printf("%.2lf",R); but it's rounding off the value.How to get the desired output ? (preferably using printf)
#include <math.h>
...
printf("%.2f", floor(100 * R) / 100);
All you have to do is subtract .005 from the number and magically printf will behave as you wish: always round down.
sprintf it into a buffer, and then put the NUL char two bytes past the '.'
Then printf your final string using the intermediate one.
If you have it, use fmod() to chop the tail of the double:
double rounded = R - fmod(R, 0.01);
// Now just print rounded with what you were using before
This has the advantage of working the same if R is positive or negative.
What about using double trunc(double) from GLibC?
Can you multiply by 100 and then truncate to an integer? Then you could format the result like one would with dollars and cents. Simply dividing by 100 might land you back at square one due to floating-point representation issues.
Another solution, using casts:
...
printf("%.2lf", (double) ((int) (R * 100)) / 100);
Another way, truly sign agnostic:
printf("%d.%d\n", (int) r ,abs((int)(r*100) % 100));