Re: Issues with rounding
- From: Joseph M. Newcomer <newcomer@xxxxxxxxxxxx>
- Date: Sun, 04 Mar 2007 01:05:12 -0500
There's a huge body of literature out there on BIGNUM algorithms including issues of
rounding.
A good start would be
http://en.wikipedia.org/wiki/Bignum
There is a classic joke about El Camino Real being known as El Camino Bignum. The story
is retold in
http://en.wikipedia.org/wiki/El_Camino_Real_(California)
joe
On Sat, 03 Mar 2007 11:05:44 -0600, "Doug Harrison [MVP]" <dsh@xxxxxxxx> wrote:
On 2 Mar 2007 12:10:09 -0800, "chris.dannemiller@xxxxxxxxx"Joseph M. Newcomer [MVP]
<chris.dannemiller@xxxxxxxxx> wrote:
Since the user is entering the data "18.05" I was wondering if there
was a way to round the string before I convert it to a float.
Certainly you can round the string representation. Start by converting the
string to mantissa and exponent, i.e. M = "1805" and E = 1. There is still
an implied decimal point so the number is really 1.805 x 10^1, but it's
easier to work on the string if you remove it. Now you need to determine
the position of the rounding digit. That's given by R = E+1+N, where N is
the number of decimal places you're rounding to. Now if M[R] == '5', work
backwards through the string until you reach something besides a '9' or
fall off the front of the string. If you reach a non-'9', increment it. If
you fall off the front, make the string "1" and increment the exponent.
Actually, if you store a '0' in the front of your buffer, then you can
always increment the digit at the cursor position once you stop the
backwards iteration. Then you truncate the string and reconstruct the
number for passing to a function like strtod. On the other hand, if M[R] <
'5', then truncate the string right there. Anyway, that's a sketch of an
algorithm. You'll have to be careful to avoid buffer overruns and
underruns, of course, and no doubt there are edge cases you'll need to
handle. Please note that once you convert "18.1" to FP, it may still be an
approximation; that is, you might end up with 18.100000000000001 or
something like that.
It seems
a trivial to approach it for decade based rounding 0.1, 0.01 ect. But
not trivial for other rounding criteria such as 0.25, 0.0625 ect.
The general formula is to divide by the rounding factor, add .5, truncate
to integer, and multiply by the factor. The idea is to treat the rounding
factor as a counting unit and convert the number to be rounded to the
nearest whole number multiple of this unit. Of course, all this
multiplication and division is subject to round-off error. I don't know how
you'd do it on the string representation.
email: newcomer@xxxxxxxxxxxx
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
.
- References:
- Issues with rounding
- From: chris.dannemiller@xxxxxxxxx
- Re: Issues with rounding
- From: Doug Harrison [MVP]
- Re: Issues with rounding
- From: chris.dannemiller@xxxxxxxxx
- Re: Issues with rounding
- From: Doug Harrison [MVP]
- Issues with rounding
- Prev by Date: Re: Handle left-click on popup menu
- Next by Date: Converting Visual C++ 6.0 application to Unicode
- Previous by thread: Re: Issues with rounding
- Next by thread: Re: Issues with rounding
- Index(es):
Relevant Pages
|