0

say I have a string as such (I am actually getting this value from somewhere else)

std::string val = "2.31";

Now I am doing something like this

float f = atof(val);

Now f has something like 2.31xxxxxxxxxxx

any suggestion on how I could just get two places after the decimal point ? such that f looks like 2.3100000...

Rajeshwar
  • 11,179
  • 26
  • 86
  • 158

3 Answers3

1

You can never get exact value for every input in float. Thats due to representation of floating point in computer. And thats also why you cant do == on floats. If you want precision, you will have to use other formats (BCD ?)

Martin Perry
  • 9,232
  • 8
  • 46
  • 114
  • 1
    `1.0==1.0` is just fine. – Benjamin Bannier Aug 26 '13 at 18:22
  • 2
    @BenjaminBannier: “1.0” is an input, not every input. – Eric Postpischil Aug 26 '13 at 18:23
  • @BenjaminBannier Let's agree that it appeared to be working so far, according to your experience. –  Aug 26 '13 at 18:23
  • @BenjaminBannier thats because its hard coded in code and not from variable. If you do this, compiler do some optimalization and place both numbers as same in memory – Martin Perry Aug 26 '13 at 18:23
  • @MartinPerry No, not quite. –  Aug 26 '13 at 18:23
  • 4
    @MartinPerry: `1.0 == 1.0` is true because `1.0` is exactly representable and every C++ implementation of even the slightest quality converts an input string of “1.0” to exactly 1. Floating-point does not introduce random changes to numbers, and they do not fluctuate spontaneously. – Eric Postpischil Aug 26 '13 at 18:24
  • @EricPostpischil I have also seen 1.0 from string represented as 1.000000000001 (or some junk at the end). Hovever, 1.0 is just one float from all possible values, so its not quite good to argument with that. – Martin Perry Aug 26 '13 at 18:26
  • 1
    @MartinPerry: Show a self-contained compilable example. – Eric Postpischil Aug 26 '13 at 18:27
  • @MartinPerry: My snarky comment was not a general, always true statement, but just geared towards the black magic your answer implied. – Benjamin Bannier Aug 26 '13 at 18:31
  • @MartinPerry: It's nothing to do with variables - even `double third() { return 1.0 / 3.0; } int main() { double a = 1.0 / 3.0; if ( a == third() ) { ...` ought to evaluate to `true`. What is true is that you often can't count on two different routes getting you to what seems like it ought to be the same number, e.g. `if ( 0.1 * 3 == 0.3 )` will generally not evaluate to `true`. – Crowman Aug 26 '13 at 19:49
1

Binary floating points cannot represent fractional, decimal values exactly. The value stored in a float will be an approximation in most cases. However, using the right algorithm for printing will restore the original digits if there are no more than std::numeric_limits<float>::digits10 digits used.

Dietmar Kühl
  • 150,225
  • 13
  • 225
  • 380
0
template <typename T>
T val(const std::string& s)
{
    T x;   
    std::stringstream ss;
    ss  << s;
    ss >> x;
   return x;
}

int main() {
float f =val<float>("2.31");
std::cout<<f; 
 }
P0W
  • 46,614
  • 9
  • 72
  • 119
  • This does not set a `float` to 2.31 as the question requests. – Eric Postpischil Aug 26 '13 at 18:21
  • @EricPostpischil 2.31 is [shown](http://ideone.com/XBdQ21) two decimal places – P0W Aug 26 '13 at 18:29
  • The question title indicates conversion to `float` is desired. Sending a numeral with two decimal places to output is not converting to `float`. The actual `float` object in the code you linked to does not have the exact value 2.31. – Eric Postpischil Aug 26 '13 at 18:31