[m-rev.] for review: fix float_to_string so that roundtripping works
Fergus Henderson
fjh at cs.mu.OZ.AU
Thu Nov 21 15:31:24 AEDT 2002
On 21-Nov-2002, Ralph Becket <rafe at cs.mu.OZ.AU> wrote:
> > On 20-Nov-2002, Peter Ross <pro at missioncriticalit.com> wrote:
> > > +:- pragma foreign_code(c, "
> > > +void
> > > +ML_sprintf_float(char *buf, MR_Float f)
> > > +{
> > > + MR_Float round;
> > > + int i = ML_MIN_PRECISION;
> > > +
> > > + do {
> > > + sprintf(buf, ""%#.*g"", i, f);
> > > + if (i >= ML_MAX_PRECISION) {
> > > + /*
> > > + ** This should be sufficient precision to
> > > + ** round-trip any value. Don't bother checking
> > > + ** whether it can actually be round-tripped,
> > > + ** since if it can't, this is a bug in the C
> > > + ** implementation.
> > > + */
> > > + break;
> > > + }
> > > + sscanf(buf, ML_FMT, &round);
> > > + i++;
> > > + } while (round != f);
> > > +}
> > > +").
>
> Small point, but isn't a for loop more appropriate here?
>
> for(i = ML_MIN_PRECISION; i <= ML_MAX_PRECISION; i++) {
> sprintf(buf, "%#.*g", i, f);
> sscanf(buf, ML_FMT, &round);
> if(round == f) {
> break;
> }
> }
That would be OK, but it's probably a little less efficient than the do-while
loop above. In the case where the number requires the maximum precision,
your loop calls sscanf() and the float equality comparison three times,
whereas the do-while loop executes these only two times.
BTW, it just occurred to me that there is a bug here with regard to the
handling of `inf' and `nan'. For those, the sscanf() call may fail,
leaving `round' uninitialized, but we go on and access `round',
which results in undefined behaviour. The uninitialized value may
happen to be a signalling NaN, in which case it would crash.
The simplest solution is to just initialize `round' (e.g. to zero).
--
Fergus Henderson <fjh at cs.mu.oz.au> | "I have always known that the pursuit
The University of Melbourne | of excellence is a lethal habit"
WWW: <http://www.cs.mu.oz.au/~fjh> | -- the last words of T. S. Garp.
--------------------------------------------------------------------------
mercury-reviews mailing list
post: mercury-reviews at cs.mu.oz.au
administrative address: owner-mercury-reviews at cs.mu.oz.au
unsubscribe: Address: mercury-reviews-request at cs.mu.oz.au Message: unsubscribe
subscribe: Address: mercury-reviews-request at cs.mu.oz.au Message: subscribe
--------------------------------------------------------------------------
More information about the reviews
mailing list