views:

2531

answers:

8

I am facing a problem and unable to resolve it. Need help from gurus. Here is sample code:-

float f=0.01f;
printf("%f",f);

if we check value in variable during debugging f contains '0.0099999998' value and output of printf is 0.010000.

a. Is there any way that we may force the compiler to assign same values to variable of float type?

b. I want to convert float to string/character array. How is it possible that only and only exactly same value be converted to string/character array. I want to make sure that no zeros are padded, no unwanted values are padded, no changes in digits as in above example.

+2  A: 

Have a look at this C++ reference. Specifically the section on precision:

float blah = 0.01;
printf ("%.2f\n", blah);
Cannonade
I think he is facing problem with floats not doubles
Aamir
BTW, I am not one who downvoted you
Aamir
hehe ... thats cool. I figure the original downvote may have been because of my first, very terse answer (sans sourcecode), and fair enough too ;).
Cannonade
Might also be because I have ignored the whole float point representation issue and answered the question on a fairly superficial level.
Cannonade
+1  A: 

Not all numbers can be represented exactly in floating point. See http://stackoverflow.com/questions/177506/why-do-i-see-a-double-variable-initialized-to-some-value-like-21-4-as-21-39999961

Sinan Ünür
+5  A: 

It is impossible to accurately represent a base 10 decimal number using base 2 values, except for a very small number of values (such as 0.25). To get what you need, you have to switch from the float/double built-in types to some kind of decimal number package.

Mark Ransom
+1  A: 

The reason that your debugger is giving you a different value is well explained in Mark Ransom's post.

Regarding printing a float without roundup, truncation and with fuller precision, you are missing the precision specifier - default precision for printf is typically 6 fractional digits.

try the following to get a precision of 10 digits:

float amount = 0.0099999998;
printf("%.10f", amount);

As a side note, a more C++ way (vs. C-style) to do things is with cout:

float amount = 0.0099999998;
cout.precision(10);
cout << amount << endl;
Demi
A: 

You would need to consult your platform standards to determine how to best determine the correct format, you would need to display it as a*b^C, where 'a' is the integral component that holds the sign, 'b' is implementation defined (Likely fixed by a standard), and 'C' is the exponent used for that number.

Alternatively, you could just display it in hex, it'd mean nothing to a human, though, and it would still be binary for all practical purposes. (And just as portable!)

Arafangion
A: 

To answer your second question:

it IS possible to exactly and unambiguously represent floats as strings. However, this requires a hexadecimal representation. For instance, 1/16 = 0.1 and 10/16 is 0.A.

With hex floats, you can define a canonical representation. I'd personally use a fixed number of digits representing the underlying number of bits, but you could also decide to strip trailing zeroes. There's no confusion possible on which trailing digits are zero.

Since the representation is exact, the conversions are reversible: f==hexstring2float(float2hexstring(f))

MSalters
+2  A: 

You could use boost::lexical_cast in this way:

float blah = 0.01;
string w = boost::lexical_cast<string>( blah );

Variable w will contain text value 0.00999999978. But I can't see when you really need it.

It is preferred to use boost::format for accurate formatting float as string. The following code shows how to do it:

float blah = 0.01;
string w = str( boost::format("%d") % blah ); // w contains exactly "0.01" now
Kirill V. Lyadvinsky
A: 

For (b), you could do

std::ostringstream os;
os << f;
std::string s = os.str();
AngryWhenHungry