Rounding, Truncating Values

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; }

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

-----Original Message----- From: boost-bounces@lists.boost.org [mailto:boost-bounces@lists.boost.org] On Behalf Of Hervé Brönnimann Sent: 02 June 2008 04:03 To: boost@lists.boost.org Subject: Re: [boost] Rounding, Truncating Values
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?
This issue has been raised before after a user noted that round-tripping via serialisation or lexical_cast did not work - always :-( http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?Feedbac... http://tinyurl.com/vhpvo The key issue is whether conversion (input) from a decimal digit string of sufficient length (17 for 64-but double for example) should *always* give the *nearest representable* double. The Standard isn't explicit about this, but the papers you mention show that it can be done, and other systems than MS manage this. I don't think Microsoft's response shows that they understand this (except that they apparently have a C# function that DOES guarantee this!) For my money, this is a simple off by one bug, but I'm not ploughing though the Dinkumware iostreams code to find where! If you don't meet this requirement, I don't think you can't expect any round tripping to work. I've glanced at the Burger and Dybvig algorithms you quote, but they don't seem too simple to implement. If any one can get they to work, they would be most valuable. Paul --- Paul A Bristow Prizet Farmhouse, Kendal, Cumbria UK LA8 8AB +44 1539561830 & SMS, Mobile +44 7714 330204 & SMS pbristow@hetp.u-net.com

Paul: Most valuable indeed. Like a bullion of gold, because in practice they aren't much slower than the run-of-the-mill sscanf/ sprintf (a few extra cycles, except once in a while in spurious boundary cases where you need more than one or two extra binary digits). But the guaranteed round-trip, and extra precision, is well worth it. But who's got the time... <insert here great proselytization about boost, library code, reuse, etc.> :) Oh, I remember fondly implementing Bellerophon in grad school (Clinger's original scanf). We had two weeks in Dave Hanson's systems programming class, 40% of the grade for the code working on the given examples, 40% for working on his test suite -- which he *didn't* give us access to, and 20% for the style/doc. In 13 weeks, we worked 13 problems (two weeks each, one week to research/read and discuss during the next class, overlapping with implementing the previous project). Projects ranged from various SIGPLAN/research recent or classical articles illustrating systems issues, e.g. this (floating point), impl. a context switcher for Solaris threads in assembler, impl. a symbolic tree manip for optimization (Dave gave us his lcc compiler, we only tweaked the optimizing module), some new/ improved graph algorithm for manipulating symbols in a linker's symbol table, a couple of hard optimization problems (with heuristics), incl. some speach audio data analysis, etc. You get the idea. Dave's class was the best programming class I ever took, and one I hope to teach again myself someday. If any teacher/instructor is listening, this is a formula I most highly recommend. Keeps everyone honest, and teaches discipline like nothing else. (Lots of work for the teacher though; Dave had set up a black-box server wherein we could test our program, and output had to be *identical*, a la ACM Competition; grading was automatic by running private test suite and diff'ing the outputs.) I got Bellerophon to work all right, it isn't that hard if you follow the math (not a small feat, though), but it requires meticulous implementation skills (and will beat it into you if you don't have it). Then begins the fun with infinities and nans... and for dessert: subnormal numbers. Either one (both?) would be a great SoC project, by the way, if any student is listening, once you have the right interface. -- Hervé Brönnimann hervebronnimann@mac.com On Jun 3, 2008, at 10:59 AM, Paul A Bristow wrote:
I've glanced at the Burger and Dybvig algorithms you quote, but they don't seem too simple to implement. If any one can get they to work, they would be most valuable.

Perhaps we can suggest it for GSoC next year? I'll try to remember to do that - but your supervision/mentoring will be invaluable. I vaguely recall that an unlimited precision integer would be needed? Or was it just a big/whopper integer? This would be valuable as a Boost thingy anyway? Paul --- Paul A Bristow Prizet Farmhouse, Kendal, Cumbria UK LA8 8AB +44 1539561830 & SMS, Mobile +44 7714 330204 & SMS pbristow@hetp.u-net.com
-----Original Message----- From: boost-bounces@lists.boost.org [mailto:boost-bounces@lists.boost.org] On Behalf Of Hervé Brönnimann Sent: 04 June 2008 06:12 To: boost@lists.boost.org Subject: Re: [boost] Rounding, Truncating Values
Paul: Most valuable indeed. Like a bullion of gold, because in practice they aren't much slower than the run-of-the-mill sscanf/ sprintf (a few extra cycles, except once in a while in spurious boundary cases where you need more than one or two extra binary digits). But the guaranteed round-trip, and extra precision, is well worth it. But who's got the time... <insert here great proselytization about boost, library code, reuse, etc.> :)
Oh, I remember fondly implementing Bellerophon in grad school (Clinger's original scanf). We had two weeks in Dave Hanson's systems programming class, 40% of the grade for the code working on the given examples, 40% for working on his test suite -- which he *didn't* give us access to, and 20% for the style/doc. In 13 weeks, we worked 13 problems (two weeks each, one week to research/read and discuss during the next class, overlapping with implementing the previous project). Projects ranged from various SIGPLAN/research recent or classical articles illustrating systems issues, e.g. this (floating point), impl. a context switcher for Solaris threads in assembler, impl. a symbolic tree manip for optimization (Dave gave us his lcc compiler, we only tweaked the optimizing module), some new/ improved graph algorithm for manipulating symbols in a linker's symbol table, a couple of hard optimization problems (with heuristics), incl. some speach audio data analysis, etc. You get the idea.
Dave's class was the best programming class I ever took, and one I hope to teach again myself someday. If any teacher/instructor is listening, this is a formula I most highly recommend. Keeps everyone honest, and teaches discipline like nothing else. (Lots of work for the teacher though; Dave had set up a black-box server wherein we could test our program, and output had to be *identical*, a la ACM Competition; grading was automatic by running private test suite and diff'ing the outputs.)
I got Bellerophon to work all right, it isn't that hard if you follow the math (not a small feat, though), but it requires meticulous implementation skills (and will beat it into you if you don't have it). Then begins the fun with infinities and nans... and for dessert: subnormal numbers.
Either one (both?) would be a great SoC project, by the way, if any student is listening, once you have the right interface. -- Hervé Brönnimann hervebronnimann@mac.com
On Jun 3, 2008, at 10:59 AM, Paul A Bristow wrote:
I've glanced at the Burger and Dybvig algorithms you quote, but they don't seem too simple to implement. If any one can get they to work, they would be most valuable.

I can perhaps offer some help designing the interface, but I'm having way more fun at programming myself than mentoring. Which is a convoluted way to say I'm too busy and would decline (at this time) mentoring any such project. If someone else was mentoring and needed a sounding board for discussion, I'd have good resonance, though :) -- Hervé Brönnimann hervebronnimann@mac.com On Jun 4, 2008, at 12:04 PM, Paul A Bristow wrote:
Perhaps we can suggest it for GSoC next year? I'll try to remember to do that - but your supervision/mentoring will be invaluable.
I vaguely recall that an unlimited precision integer would be needed? Or was it just a big/whopper integer? This would be valuable as a Boost thingy anyway?
Paul
--- Paul A Bristow Prizet Farmhouse, Kendal, Cumbria UK LA8 8AB +44 1539561830 & SMS, Mobile +44 7714 330204 & SMS pbristow@hetp.u-net.com
-----Original Message----- From: boost-bounces@lists.boost.org [mailto:boost-bounces@lists.boost.org] On Behalf Of Hervé Brönnimann Sent: 04 June 2008 06:12 To: boost@lists.boost.org Subject: Re: [boost] Rounding, Truncating Values
Paul: Most valuable indeed. Like a bullion of gold, because in practice they aren't much slower than the run-of-the-mill sscanf/ sprintf (a few extra cycles, except once in a while in spurious boundary cases where you need more than one or two extra binary digits). But the guaranteed round-trip, and extra precision, is well worth it. But who's got the time... <insert here great proselytization about boost, library code, reuse, etc.> :)
Oh, I remember fondly implementing Bellerophon in grad school (Clinger's original scanf). We had two weeks in Dave Hanson's systems programming class, 40% of the grade for the code working on the given examples, 40% for working on his test suite -- which he *didn't* give us access to, and 20% for the style/doc. In 13 weeks, we worked 13 problems (two weeks each, one week to research/read and discuss during the next class, overlapping with implementing the previous project). Projects ranged from various SIGPLAN/research recent or classical articles illustrating systems issues, e.g. this (floating point), impl. a context switcher for Solaris threads in assembler, impl. a symbolic tree manip for optimization (Dave gave us his lcc compiler, we only tweaked the optimizing module), some new/ improved graph algorithm for manipulating symbols in a linker's symbol table, a couple of hard optimization problems (with heuristics), incl. some speach audio data analysis, etc. You get the idea.
Dave's class was the best programming class I ever took, and one I hope to teach again myself someday. If any teacher/instructor is listening, this is a formula I most highly recommend. Keeps everyone honest, and teaches discipline like nothing else. (Lots of work for the teacher though; Dave had set up a black-box server wherein we could test our program, and output had to be *identical*, a la ACM Competition; grading was automatic by running private test suite and diff'ing the outputs.)
I got Bellerophon to work all right, it isn't that hard if you follow the math (not a small feat, though), but it requires meticulous implementation skills (and will beat it into you if you don't have it). Then begins the fun with infinities and nans... and for dessert: subnormal numbers.
Either one (both?) would be a great SoC project, by the way, if any student is listening, once you have the right interface. -- Hervé Brönnimann hervebronnimann@mac.com
On Jun 3, 2008, at 10:59 AM, Paul A Bristow wrote:
I've glanced at the Burger and Dybvig algorithms you quote, but they don't seem too simple to implement. If any one can get they to work, they would be most valuable.
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/ listinfo.cgi/boost
participants (4)
-
Frank Birbacher
-
Hervé Brönnimann
-
Paul A Bristow
-
Tom Brinkman