Re: Can printf() be made smarter?
- Posted by petelomax Nov 02, 2018
- 1176 views
printf(fn,"%.2f\n",x) returns 12845.81
but what if the number had 3 or more decimal places, which some in this file do?
You could try something like fmt=sprintf("%%.%df\n",ndp); printf(fn,fmt,x).
So we give up on %f, which by default always shows 6 decimal places unless told otherwise, and try %g
printf(fn,"%g\n",x) returns 12845.8
What happened to the 1?
There is a subtle but important difference between %f and %g:
Field widths can be added to the basic formats, e.g. %5d, %8.2f, %10.4s. The number before the decimal point is the minimum field width to be used. The number after the decimal point is the precision to be used.
For %f and %e, the precision specifies how many digits follow the decimal point character, whereas for %g, the precision specifies how many significant digits to print...
Note that "%f" is effectively identical to "%.6f", and, albeit with that subtle difference in mind, "%g" is equivalent to "%.6g", I think.
printf(fn,"%8g\n",x) returns _12845.8 (where _ means space)
"%.8g" fares better.
Incidentally, this is weird:
printf(fn,"%.3g\n",x) returns 1.28e+04.
How is that the most appropriate way to display this number?
1.28e+04 == 12800, which is 12845.81 to 3 significant figures, jut like you asked. It gets its knickers in a bit of a twist because length("12800")>3, or something like that.
I know I can fix it by, for example, s = sprintf("%.16f",x) then a loop to delete trailing zeros from s and puts(fn,s). I'll probably include that in a function in my program, messy as it is.
Yep, messy as it is, best way I ever found. Other options may include (OE) routines like display() perhaps, outside my ken.
Can Euphoria be made 'smarter' to fix C's lack of smarts with both %f and %g, perhaps in future versions?
That would break (far too much) existing code.
If you are looking for a "pure-eu" version of printf(), dig out builtins\VM\pprntfN.e from https://bitbucket.org/petelomax/phix/src
It will now need a couple of tweaks (replace "#ilASM") to run on OE, but there should be all the compatible code needed right there, just commented out.
Pete