Tuesday 10 April 2018

C++11: a pitfall in std::to_string(float) and std::to_string(double)

1. Root cause
The problem with these two functions is that the precision of the conversion is hard coded as 6 decimals and it is not possible to adjust it.

2. What happened to me?
I made such a mistake when implementing one of services. It is to take live market FX price as input to compute a user-defined price, simple cases like mid price or WAP (weighted average price), convert the price into string (pass to the down stream service via XML), and then reconstruct or compute numeric risk values. It works OK for most currencies but not for JPY. 

It sounds bizarre but the fundamental issue is that the live market price based on JPY instruments is already in 6 decimal precision and the following calculations requires higher precision to make sure the reconstruction and risk value computation correct. But std::to_string(double) has only 6 decimal precision and the 6th decimal is rounded. This causes numeric risk computation failure - the value swing around even though the price is in trend.

3. Solution
The std::to_string manual on cppreference only says it "would produce for sufficiently large buf". No mention about conversion precision. Nor there is a second parameter to specify required precision in the function signature. Easy to make mistake. Lesson learned: always keep in mind floating-point number is different from integer in terms of underflow, overflow, comparison and string conversion. And the solution is rather simple - use string stream and io manipulator. 

No comments:

Post a Comment