5

Why does the following code gives me the different results when I write "2.01" and "2.02"?

#include <boost/lexical_cast.hpp> #include <iostream> #include <string> int main() { const std::string str = "2.02"; try { const double b = boost::lexical_cast<double>(str) * 100.0; std::cout << "double: " << b << '\n'; const int a = boost::lexical_cast<int>(b); std::cout << "int: " << a << '\n'; } catch (const std::exception& ex) { std::cerr << ex.what() << '\n'; } } 

Output

double: 202 int: 202 

But if I change "2.02" to the "2.01" it gives me the following output:

double: 201 bad lexical cast: source type value could not be interpreted as target 

Why?

I'm using Visual Studio 2013 (msvc-12.0) and boost 1.57.

Thanks in advance.

1 Answer 1

2

It's floating point inaccuracy.

There's no exact representation of 2.01 in binary floating point so, multiplying by 100 doesn't result in an integer number.

You can make it visible: Live On Coliru

std::cout << "double: " << std::setprecision(18) << std::fixed << b << '\n'; 

Prints

double: 200.999999999999971578 

Conversion to int fails for this reason.

Sign up to request clarification or add additional context in comments.

4 Comments

The solution would be to cast it to double first, and then to it, right?
Can lexical_cast be used for numeric conversions like in OP's code? isn't it designed only for conversions to/from a string-like type?
@g.tsh No. The solution would be to use decimal representation or integral arithmetics. And don't forget about the fact that decimal representations still have precision limits (like 10/3 = 3.333333...)
@PiotrS. That's a funny question (it's answered by the code running). Anyhoops Returns the result of streaming arg into a standard library string-based stream and then out as a Target object

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.