Re: Formatted printing (D5.1 and D6)
Posted by Chris Uppal-3 on Mar 26, 2006; 11:05am
URL: https://forum.world.st/Formatted-printing-D5-1-and-D6-tp3378016p3378023.html
Peter.
> '%8.4f' sprintfWith: 1.2345
Floating point and 64-bit integers don't work with variadic external functions
such as the printf() family.
The reason is that these numbers are represented (to the external code) as
>32-bit quantities. Normally Dolphin knows how to do the translation, but that
is only possible if Dolphin knows that a translation is /required/. That will
be the case if the function is defined to take a 'double' argument (for
instance). Unfortunately, the variadic functions rely on the native stack
format, plus some magic (in the external function itself) which knows how to
unravel the stack structure. So if a C function calls:
printf("%f", 3.14)
then the C compiler will (this is over-simplified) push a pointer to the format
string, and 64-bits worth of floating point data onto the stack. The code
implementing printf() will /parse/ the format string to find out what else to
expect on the stack, and can get at the various arguments from that. The
/only/ thing that tells it what the arguments are is the contents of the format
string -- if that's wrong then Nasty Things Will Happen... Now Dolphin can't
parse the string (well, it /could/, but that would require special-case code
for every variadic function), so it doesn't know what structure to build on the
stack. So it compromises by just converting everything to a 32-bit form, and
pushing that. That works fine for <=32 bit integers, characters, strings, and
whatnot. It /doesn't/ work for floats.
FWIW, I have a package that lets you talk to a wider range of variadic external
functions, which includes (as an example application)
String>>sprintfWithArguments: which will format floating-point (and other)
data. E.g:
'%010.4f' sprintfWithArguments: #( 3.14159265358979 )
See the package 'CU Varargs' under Miscellanea if you're interested.
-- chris