rg2c+@andrew.cmu.edu (Robert Nelson Gasch) (12/07/90)
Hi, I'm looking for an *efficient* algorithm to transform a float (10< f < 0) into a string. What I am doing right no is this: I get the first digit and put the appropriate number in array[0]. Array[1] gets the decimal point. I then make f < 1 and multiply it times 10, and get the aproriate character for the first digit and repeat this procedure until the number equals 0. Sounds OK, but when you do this alot, it's pretty damn slow. If anybody has any suggestions on how to do this faster, please let me know. Both actual code or algorithm descriptions are welcome. Thanx alot --> Rob
peterh@hemel.bull.co.uk (Peter Holditch) (12/07/90)
rg2c+@andrew.cmu.edu (Robert Nelson Gasch) writes: >Hi, >I'm looking for an *efficient* algorithm to transform a float (10< f < 0) >into a string. What I am doing right no is this: > [ Stuff Deleted ] >If anybody has any suggestions on how to do this faster, please let me >know. Both actual code or algorithm descriptions are welcome. >Thanx alot --> Rob It may be that you don't consider it efficient enough, but why not just use char fltno[12]; ... sprintf (fltno,"%10f",your_float); That's what I'd do anyway. Peter Holditch. -- # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # From: Peter.Holditch@hemel.bull.co.uk # # Tel: 0442-232222x4826 # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # << If I said it, it was nobody else but me. >>
gordon@osiris.cso.uiuc.edu (John Gordon) (12/08/90)
Try looking at the function gcvt().
lerman@stpstn.UUCP (Ken Lerman) (12/09/90)
In article <QbLnB1u00WBMM53Wpp@andrew.cmu.edu> rg2c+@andrew.cmu.edu (Robert Nelson Gasch) writes:
->Hi,
->I'm looking for an *efficient* algorithm to transform a float (10< f < 0)
->into a string. What I am doing right no is this:
->
->I get the first digit and put the appropriate number in array[0].
->Array[1] gets the decimal point. I then make f < 1 and multiply it
->times 10, and get the aproriate character for the first digit and
->repeat this procedure until the number equals 0. Sounds OK, but when
->you do this alot, it's pretty damn slow.
->
->If anybody has any suggestions on how to do this faster, please let me
->know. Both actual code or algorithm descriptions are welcome.
->
->Thanx alot --> Rob
You've got the right idea, but:
1 -- You should first convert the number from float to scaled integer.
2 -- Rather than multiplying by 10, shift left two, add the original
and shift left again. (A smart compiler might do this for you.)
[Some might say that a reasonable compiler should do this for you.]
3 -- You didn't say how may digits of precision you want. The
multiple-precision scaled integer multiplication can be a pain if
you want high precision.
Ken
hilfingr@rama.cs.cornell.edu (Paul N. Hilfinger) (12/10/90)
In article <QbLnB1u00WBMM53Wpp@andrew.cmu.edu> rg2c+@andrew.cmu.edu (Robert Nelson Gasch) writes: >I'm looking for an *efficient* algorithm to transform a float (10< f < 0) >into a string. What I am doing right [now] is ... [repeatedly peeling off the >most significant digit by truncation and subtraction, followed by >by 10.0, all in floating-point arithmetic.] >If anybody has any suggestions on how to do this faster, please let me >know. Both actual code or algorithm descriptions are welcome. There have been a couple of responses to this posting suggesting the use of gcvt or of scaling, conversion to integer, followed by conversion to ASCII. I was a little curious about these suggestions. Some experimentation showed that on a DECstation 3100, using cc, Mr. Gasch's original program is faster than either of the suggestions for 6 digits of result (at least for my C versions of his algorithm and the alternatives). I only find this interesting because it reminded me (still one more time) that my intuitions about double-precision floating-point performance---formed 20 years ago---need constant re-examination. (Needless to say, however, it would be unwise to generalize my findings to other processors just now.) Paul Hilfinger
steve@taumet.com (Stephen Clamage) (12/11/90)
lerman@stpstn.UUCP (Ken Lerman) writes: >2 -- Rather than multiplying by 10, shift left two, add the original > and shift left again. (A smart compiler might do this for you.) > [Some might say that a reasonable compiler should do this for you.] Except that on some machines shifting is not cheap. On some machines an integer multiply by 10 is faster than two shifts and an add along with creating an intermediate result. A good rule is to leave it up to the compiler until performance tests prove you must do low-level coding like this. In that case, be sure to conditionalize the code for the particular compiler. -- Steve Clamage, TauMetric Corp, steve@taumet.com
kaleb@thyme.jpl.nasa.gov (Kaleb Keithley ) (12/11/90)
Stepping into the middle of the thread. On Sun; there is econvert and related functions. econvert() converts the value to a null-terminated string of ndigit ASCII digits in buf and returns a pointer to buf. buf should contain at least ndigit+1 characters. The posi- tion of the radix character relative to the beginning of the string is stored indirectly through decpt. Thus buf == "314" and *decpt == 1 corresponds to the numerical value 3.14, while buf == "314" and *decpt == -1 corresponds to the numerical value .0314. If the sign of the result is nega- tive, the word pointed to by sign is nonzero; otherwise it is zero. The least significant digit is rounded. fconvert works much like econvert, except that the correct digit has been rounded as if for sprintf(%w.nf) output with n=ndigit digits to the right of the radix character. ndigit can be negative to indicate rounding to the left of the radix character. The return value is a pointer to buf. buf should contain at least 310+max(0,ndigit) characters to accomodate any double-precision value. gconvert() converts the value to a null-terminated ASCII string in buf and returns a pointer to buf. It produces ndigit significant digits in fixed-decimal format, like sprintf(%w.nf), if possible, and otherwise in floating- decimal format, like sprintf(%w.ne); in either case buf is ready for printing, with sign and exponent. The result corresponds to that obtained by (void) sprintf(buf, "%w.ng", value); -- Kaleb Keithley Jet Propulsion Labs kaleb@thyme.jpl.nasa.gov You can please all of the people some of the time,
gwyn@smoke.brl.mil (Doug Gwyn) (12/11/90)
In article <49508@cornell.UUCP> hilfingr@cs.cornell.edu (Paul N. Hilfinger) writes: >Gasch's original program is faster than either of the suggestions ... But the library routines probably round correctly and properly convert numbers that are approximately an exact power of 10.