
Dear Tom: I'm not even sure I understand the contract. How can you round to a number of decimal places when the result is not necessarily representable? Rather than an implementation, could you provide an example of a documentation, stating precisely what the return value should be? Also, if the intention is float/double/long double, why templates, as opposed to three overloads? Thanks for any clarification. Equally useful as rounding, perhaps, would be printing to a string with guaranteed rounding. You know that printing or reading a binary floating point to a decimal string representation, and back, may not result in the same number. This goes with printf and scanf, as well as I/O streams (perhaps this has been corrected but I haven't seen anything very sophisticated in the STL implementations I lurk in). There are known algorithms to do this with guaranteed rounding, e.g.: - Guy L. Steele , Jon L. White, How to print floating-point numbers accurately, ACM SIGPLAN Notices, v.39 n.4, April 2004 - William D. Clinger, How to read floating point numbers accurately, ACM SIGPLAN Notices, v.39 n.4, April 2004 (Both papers are old, 1990 and 1991, but the more recent reference/ reprint may have added information, or may be more accessible.) Also: - Robert G. Burger , R. Kent Dybvig, Printing floating-point numbers quickly and accurately, ACM SIGPLAN Notices, v.31 n.5, p.108-116, May 1996 Now those would be very nice to have. It appears that numeric_cast library would be the natural host for your proposed functionality, and lexical_cast library would be the natural host for the one I'm asking for above. It doesn't seem that anything like this is in those libraries, though, I rechecked both ToC. Is there anything like this in boost? -- Hervé Brönnimann hervebronnimann@mac.com On May 30, 2008, at 6:29 PM, Tom Brinkman wrote:
Here are a few small utility functions that I use for rounding and truncating values. Its probably a good idea to add this functionality to boost. However, I'm sure that the implentations could be significantly improved.
enum RoundDirection { rd_AwayZero=0, rd_TowardZero=1, };
template <class A> inline A roundTo(A val, int decimalPlaces) { double mult=pow(10.0, decimalPlaces); return round(val*mult)/mult; }
template <class A> inline A roundTo(A val, int decimalPlaces, RoundDirection rd) { A ret; double mult=pow(10.0, decimalPlaces); bool less0=(val<0.0 ? true : false);
if (less0) { if (rd==rd_AwayZero) rd=rd_TowardZero; else if (rd==rd_TowardZero) rd=rd_AwayZero; }
switch (rd) { case rd_AwayZero: ret=ceil(val*mult)/mult; break; case rd_TowardZero: ret=floor(val*mult)/mult; }
return ret; }
template <class A> inline A truncTo(A val, int decimalPlaces) { double mult=pow(10.0, decimalPlaces); return trunc(val*mult)/mult; } _______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/ listinfo.cgi/boost