[v][sf]printf additions (#, E, g, G)

php.internals

Matt W

20 years ago
Hi, I've wished there was a *printf() float specifier that wouldn't include trailing zeros/point, as simply converting to string (echo, %s, etc.) can result in scientific notation, which I *don't* want (%g in convert_to_string()). The only other way that would result in what I want is number_format() with my "no-extra-zeros option" patch. ;-) So I was originally looking for how to NOT pad %f to the specified precision, then I thought why not add more of the stuff from C? (And I see it's marked "not done" in formatted_print.c.) Can/should I go ahead and add support for the # flag/specifier, g/G, and E (the missing compliment to e)? Make everything work like C, except # used with f/F, which would mean "remove trailing 0's/point" -- as C's behavior with # and f (add point even when precision=0?) can be done in PHP. (I assume C's is for when precision is specified with * + parameter?) Thoughts? Thanks, Matt

Marcus Börger

20 years ago
Hello Matt, Thursday, July 20, 2006, 2:20:46 PM, you wrote:
> Hi,
> I've wished there was a *printf() float specifier that wouldn't include > trailing zeros/point, as simply converting to string (echo, %s, etc.) can > result in scientific notation, which I *don't* want (%g in > convert_to_string()). The only other way that would result in what I want > is number_format() with my "no-extra-zeros option" patch. ;-) So I was > originally looking for how to NOT pad %f to the specified precision, then I > thought why not add more of the stuff from C? (And I see it's marked "not > done" in formatted_print.c.)
> Can/should I go ahead and add support for the # flag/specifier, g/G, and E > (the missing compliment to e)? Make everything work like C, except # used > with f/F, which would mean "remove trailing 0's/point" -- as C's behavior > with # and f (add point even when precision=0?) can be done in PHP. (I > assume C's is for when precision is specified with * + parameter?)
Having more conversion specifiers here won't hurt. If it can be done in a way compatible to other languages especially like C it should be done in that way. If PHP has already closed the way by choosing opposite defaults the opposite should everntually also work. Best regards, Marcus

Matt W

20 years ago
Hi Marcus, ----- Original Message ----- From: "Marcus Boerger" Sent: Thursday, July 20, 2006 2:21 PM Subject: Re: [PHP-DEV] [v][sf]printf additions (#, E, g, G)
> Hello Matt, > > Thursday, July 20, 2006, 2:20:46 PM, you wrote: > > > Hi, > > > I've wished there was a *printf() float specifier that wouldn't include > > trailing zeros/point, as simply converting to string (echo, %s, etc.)
can
> > result in scientific notation, which I *don't* want (%g in > > convert_to_string()). The only other way that would result in what I
want
> > is number_format() with my "no-extra-zeros option" patch. ;-) So I was > > originally looking for how to NOT pad %f to the specified precision,
then I
> > thought why not add more of the stuff from C? (And I see it's marked
"not
> > done" in formatted_print.c.) > > > Can/should I go ahead and add support for the # flag/specifier, g/G, and
E
> > (the missing compliment to e)? Make everything work like C, except #
used
> > with f/F, which would mean "remove trailing 0's/point" -- as C's
behavior
> > with # and f (add point even when precision=0?) can be done in PHP. (I > > assume C's is for when precision is specified with * + parameter?) > > Having more conversion specifiers here won't hurt. If it can be done > in a way compatible to other languages especially like C it should be > done in that way. If PHP has already closed the way by choosing opposite > defaults the opposite should everntually also work.
Sorry, not sure what you mean in the last sentence as far as the additions I'm asking about. I agree about compatibility with C's specifiers, but PHP's *printf() has things that C's doesn't (%b; alternate padding specifier) and vice versa (PHP's doesn't support "*" width/precision -- nor does it need to; also no %n). That's why I thought it would be OK to let # with f/F mean no trailing 0's. Other than that, g/G would, of course, be new. Unless it's not needed if 1) my "alternate form" %f idea is added, or 2) its precision would confuse users since it means "number of significant digits" with g/G, rather than decimal places. # with e/E would include the decimal point even if precision=0 # with g/G *wouldn't* strip trailing 0's # with o would include "0" prefix with non-zero result # with x/X would include "0x"/"0X" prefix with non-zero result All like C AFAIK, again except %#.3f, for example, wouldn't have trailing zeros/point. As you can probably tell, I don't like extra 0's unless there's a *need* to always have the same width (same idea with number_format()). :-) I'm sure other PHP users feel the same way and would like this alternate %f form, even if no other language has it!
> Best regards, > Marcus
Thanks for the reply, Matt

Marcus Börger

20 years ago
Hello Matt, sounds good then, keep going. best regards marcus Friday, July 21, 2006, 10:08:19 AM, you wrote:
> Hi Marcus,
> ----- Original Message ----- > From: "Marcus Boerger" > Sent: Thursday, July 20, 2006 2:21 PM > Subject: Re: [PHP-DEV] [v][sf]printf additions (#, E, g, G)
>> Hello Matt, >> >> Thursday, July 20, 2006, 2:20:46 PM, you wrote: >> >> > Hi, >> >> > I've wished there was a *printf() float specifier that wouldn't include >> > trailing zeros/point, as simply converting to string (echo, %s, etc.) > can >> > result in scientific notation, which I *don't* want (%g in >> > convert_to_string()). The only other way that would result in what I > want >> > is number_format() with my "no-extra-zeros option" patch. ;-) So I was >> > originally looking for how to NOT pad %f to the specified precision, > then I >> > thought why not add more of the stuff from C? (And I see it's marked > "not >> > done" in formatted_print.c.) >> >> > Can/should I go ahead and add support for the # flag/specifier, g/G, and > E >> > (the missing compliment to e)? Make everything work like C, except # > used >> > with f/F, which would mean "remove trailing 0's/point" -- as C's > behavior >> > with # and f (add point even when precision=0?) can be done in PHP. (I >> > assume C's is for when precision is specified with * + parameter?) >> >> Having more conversion specifiers here won't hurt. If it can be done >> in a way compatible to other languages especially like C it should be >> done in that way. If PHP has already closed the way by choosing opposite >> defaults the opposite should everntually also work.
> Sorry, not sure what you mean in the last sentence as far as the additions > I'm asking about. I agree about compatibility with C's specifiers, but > PHP's *printf() has things that C's doesn't (%b; alternate padding > specifier) and vice versa (PHP's doesn't support "*" width/precision -- nor > does it need to; also no %n). That's why I thought it would be OK to let # > with f/F mean no trailing 0's.
> Other than that, g/G would, of course, be new. Unless it's not needed if 1) > my "alternate form" %f idea is added, or 2) its precision would confuse > users since it means "number of significant digits" with g/G, rather than > decimal places.
> # with e/E would include the decimal point even if precision=0 > # with g/G *wouldn't* strip trailing 0's > # with o would include "0" prefix with non-zero result > # with x/X would include "0x"/"0X" prefix with non-zero result
> All like C AFAIK, again except %#.3f, for example, wouldn't have trailing > zeros/point. As you can probably tell, I don't like extra 0's unless > there's a *need* to always have the same width (same idea with > number_format()). :-) I'm sure other PHP users feel the same way and would > like this alternate %f form, even if no other language has it!
>> Best regards, >> Marcus
> Thanks for the reply, > Matt
Best regards, Marcus

Matt W

20 years ago
Hi Marcus, Cool, thanks. I didn't start modifying it yet, but will soon. Matt ----- Original Message ----- From: "Marcus Boerger" Sent: Friday, July 21, 2006
> Hello Matt, > > sounds good then, keep going. > > best regards > marcus > > Friday, July 21, 2006, 10:08:19 AM, you wrote: > > > Hi Marcus, > > > ----- Original Message ----- > > From: "Marcus Boerger" > > Sent: Thursday, July 20, 2006 2:21 PM > > Subject: Re: [PHP-DEV] [v][sf]printf additions (#, E, g, G) > > >> Hello Matt, > >> > >> Having more conversion specifiers here won't hurt. If it can be done > >> in a way compatible to other languages especially like C it should be > >> done in that way. If PHP has already closed the way by choosing
opposite
> >> defaults the opposite should everntually also work. > > > Sorry, not sure what you mean in the last sentence as far as the
additions
> > I'm asking about. I agree about compatibility with C's specifiers, but > > PHP's *printf() has things that C's doesn't (%b; alternate padding > > specifier) and vice versa (PHP's doesn't support "*" width/precision --
nor
> > does it need to; also no %n). That's why I thought it would be OK to
let #
> > with f/F mean no trailing 0's. > > > Other than that, g/G would, of course, be new. Unless it's not needed
if 1)
> > my "alternate form" %f idea is added, or 2) its precision would confuse > > users since it means "number of significant digits" with g/G, rather
than
> > decimal places. > > > # with e/E would include the decimal point even if precision=0 > > # with g/G *wouldn't* strip trailing 0's > > # with o would include "0" prefix with non-zero result > > # with x/X would include "0x"/"0X" prefix with non-zero result > > > All like C AFAIK, again except %#.3f, for example, wouldn't have
trailing
> > zeros/point. As you can probably tell, I don't like extra 0's unless > > there's a *need* to always have the same width (same idea with > > number_format()). :-) I'm sure other PHP users feel the same way and
would

Matt W

20 years ago
Hi Marcus, all, I finally started on these additions and noticed a couple things... 1) Using %.4e, for example, only gives 3 decimal places instead of 4 -- I assume I can/should fix that? 2) I realized "precision" isn't supported with d/u/o/x etc., just width+padding. Precision could be used for minimum *number* width (left-pad with 0s if needed) *and* have a minimum *field* width with non-0 padding. So should I add "precision" support for the aforementioned specifiers? 3) Is it OK to modify the parameters of the php_sprintf_* functions? It's necessary in order to add some of these things. Also, could the _appendint and _appenduint functions be combined? They're mostly duplicate code, and doing so would save a "char numbuf[500]" array... Thanks, Matt ----- Original Message ----- From: "Marcus Boerger" Sent: Friday, July 21, 2006
> Hello Matt, > > sounds good then, keep going. > > best regards > marcus > > Friday, July 21, 2006, 10:08:19 AM, you wrote: > > > Hi Marcus, > > > ----- Original Message ----- > > From: "Marcus Boerger" > > Sent: Thursday, July 20, 2006 2:21 PM > > Subject: Re: [PHP-DEV] [v][sf]printf additions (#, E, g, G) > > > >> Hello Matt, > >> > >> Thursday, July 20, 2006, 2:20:46 PM, you wrote: > >> > >> > Hi, > >> > >> > I've wished there was a *printf() float specifier that wouldn't
include
> >> > trailing zeros/point, as simply converting to string (echo, %s, etc.) > > can > >> > result in scientific notation, which I *don't* want (%g in > >> > convert_to_string()). The only other way that would result in what I > > want > >> > is number_format() with my "no-extra-zeros option" patch. ;-) So I
was
> >> > originally looking for how to NOT pad %f to the specified precision, > > then I > >> > thought why not add more of the stuff from C? (And I see it's marked > > "not > >> > done" in formatted_print.c.) > >> > >> > Can/should I go ahead and add support for the # flag/specifier, g/G,
and
> > E > >> > (the missing compliment to e)? Make everything work like C, except # > > used > >> > with f/F, which would mean "remove trailing 0's/point" -- as C's > > behavior > >> > with # and f (add point even when precision=0?) can be done in PHP.
(I
> >> > assume C's is for when precision is specified with * + parameter?) > >> > >> Having more conversion specifiers here won't hurt. If it can be done > >> in a way compatible to other languages especially like C it should be > >> done in that way. If PHP has already closed the way by choosing
opposite
> >> defaults the opposite should everntually also work. > > > Sorry, not sure what you mean in the last sentence as far as the
additions
> > I'm asking about. I agree about compatibility with C's specifiers, but > > PHP's *printf() has things that C's doesn't (%b; alternate padding > > specifier) and vice versa (PHP's doesn't support "*" width/precision --
nor
> > does it need to; also no %n). That's why I thought it would be OK to
let #
> > with f/F mean no trailing 0's. > > > Other than that, g/G would, of course, be new. Unless it's not needed
if 1)
> > my "alternate form" %f idea is added, or 2) its precision would confuse > > users since it means "number of significant digits" with g/G, rather
than
> > decimal places. > > > # with e/E would include the decimal point even if precision=0 > > # with g/G *wouldn't* strip trailing 0's > > # with o would include "0" prefix with non-zero result > > # with x/X would include "0x"/"0X" prefix with non-zero result > > > All like C AFAIK, again except %#.3f, for example, wouldn't have
trailing
> > zeros/point. As you can probably tell, I don't like extra 0's unless > > there's a *need* to always have the same width (same idea with > > number_format()). :-) I'm sure other PHP users feel the same way and
would

Gwynne

20 years ago
On Jul 20, 2006, at 3:21 PM, Marcus Boerger wrote:
>> I've wished there was a *printf() float specifier that wouldn't >> include >> trailing zeros/point, as simply converting to string (echo, %s, >> etc.) can >> result in scientific notation, which I *don't* want (%g in >> convert_to_string()). The only other way that would result in >> what I want >> is number_format() with my "no-extra-zeros option" patch. ;-) So >> I was >> originally looking for how to NOT pad %f to the specified >> precision, then I >> thought why not add more of the stuff from C? (And I see it's >> marked "not >> done" in formatted_print.c.) > >> Can/should I go ahead and add support for the # flag/specifier, g/ >> G, and E >> (the missing compliment to e)? Make everything work like C, >> except # used >> with f/F, which would mean "remove trailing 0's/point" -- as C's >> behavior >> with # and f (add point even when precision=0?) can be done in >> PHP. (I >> assume C's is for when precision is specified with * + parameter?) > Having more conversion specifiers here won't hurt. If it can be done > in a way compatible to other languages especially like C it should be > done in that way. If PHP has already closed the way by choosing > opposite > defaults the opposite should everntually also work.
While we're on the subject, one of my favorite personal patches to PHP is one that adds the %n specifier. The parameter to %n is a reference which recieves the total length of the string with all replacements so far. %n itself is replaced by nothing at all. You could do this with $n = strlen( $s = sprintf( blah blah blah ) ) + strlen( $s .= sprintf( the rest of the blah ) );, but it's a very nice shortcut if you need the replaced length in the middle of the conversion or for a situation like this (and the above doesn't work too well if you have positional params!): printf( "Some processing message with %s replacements...%n", 'some', & $n ); // do some stuff here print str_repeat( ' ', $n ) . "\rSome status text here that doesn't worry about whether the replaced text was longer."; Here's the printf(3) manpage description for %n (MacOS X system, BSD manpage): n The number of characters written so far is stored into the inte- ger indicated by the int * (or variant) pointer argument. No argument is converted. Any chance of getting this into PHP? I can provide a patch. -- Gwynne, Daughter of the Code "This whole world is an asylum for the incurable."

Matt W

20 years ago
Hi Gwynne, ----- Original Message ----- From: "Gwynne" Sent: Saturday, July 22, 2006
> On Jul 20, 2006, at 3:21 PM, Marcus Boerger wrote: > >> I've wished there was a *printf() float specifier that wouldn't > >> include > >> trailing zeros/point, as simply converting to string (echo, %s, > >> etc.) can > >> result in scientific notation, which I *don't* want (%g in > >> convert_to_string()). The only other way that would result in > >> what I want > >> is number_format() with my "no-extra-zeros option" patch. ;-) So > >> I was > >> originally looking for how to NOT pad %f to the specified > >> precision, then I > >> thought why not add more of the stuff from C? (And I see it's > >> marked "not > >> done" in formatted_print.c.) > > > >> Can/should I go ahead and add support for the # flag/specifier, g/ > >> G, and E > >> (the missing compliment to e)? Make everything work like C, > >> except # used > >> with f/F, which would mean "remove trailing 0's/point" -- as C's > >> behavior > >> with # and f (add point even when precision=0?) can be done in > >> PHP. (I > >> assume C's is for when precision is specified with * + parameter?) > > Having more conversion specifiers here won't hurt. If it can be done > > in a way compatible to other languages especially like C it should be > > done in that way. If PHP has already closed the way by choosing > > opposite > > defaults the opposite should everntually also work. > > While we're on the subject, one of my favorite personal patches to > PHP is one that adds the %n specifier. The parameter to %n is a > reference which recieves the total length of the string with all > replacements so far. %n itself is replaced by nothing at all. You > could do this with $n = strlen( $s = sprintf( blah blah blah ) ) + > strlen( $s .= sprintf( the rest of the blah ) );, but it's a very > nice shortcut if you need the replaced length in the middle of the > conversion or for a situation like this (and the above doesn't work > too well if you have positional params!): > > printf( "Some processing message with %s replacements...%n", 'some', & > $n ); > // do some stuff here > print str_repeat( ' ', $n ) . "\rSome status text here that doesn't > worry about whether the replaced text was longer."; > > Here's the printf(3) manpage description for %n (MacOS X system, BSD > manpage): > > n The number of characters written so far is stored into > the inte- > ger indicated by the int * (or variant) pointer > argument. No > argument is converted. > > Any chance of getting this into PHP? I can provide a patch. > > -- Gwynne, Daughter of the Code > "This whole world is an asylum for the incurable."
I had thought about adding %n too, but didn't know what the reaction would be or if it'd be used. (And the length thing would have to be changed [later] for Unicode length or such, I assume?) Also, wasn't sure about the internals code for the reference and writing to it, etc. :-) Sounds fine to me though, if your patch can be applied. If PHP gets these additions, it'll have all of C's except %p I guess. :-) Matt

Gwynne

20 years ago
On Jul 23, 2006, at 5:38 AM, Matt W wrote:
>> While we're on the subject, one of my favorite personal patches to >> PHP is one that adds the %n specifier. The parameter to %n is a >> reference which recieves the total length of the string with all >> replacements so far. %n itself is replaced by nothing at all. You >> could do this with $n = strlen( $s = sprintf( blah blah blah ) ) + >> strlen( $s .= sprintf( the rest of the blah ) );, but it's a very >> nice shortcut if you need the replaced length in the middle of the >> conversion or for a situation like this (and the above doesn't work >> too well if you have positional params!): >> >> printf( "Some processing message with %s replacements...%n", >> 'some', & >> $n ); >> // do some stuff here >> print str_repeat( ' ', $n ) . "\rSome status text here that doesn't >> worry about whether the replaced text was longer."; >> >> Here's the printf(3) manpage description for %n (MacOS X system, BSD >> manpage): >> >> n The number of characters written so far is stored into >> the inte- >> ger indicated by the int * (or variant) pointer >> argument. No >> argument is converted. >> >> Any chance of getting this into PHP? I can provide a patch. > I had thought about adding %n too, but didn't know what the > reaction would > be or if it'd be used. (And the length thing would have to be changed > [later] for Unicode length or such, I assume?) Also, wasn't sure > about the > internals code for the reference and writing to it, etc. :-)
I'm completely unversed in the current Unicode stuff; I can only provide a patch against 5.2. Someone who knows the Unicode crud would have to update it for HEAD, and given the recent loud argument about HEAD vs branch commits, I don't know how well a 5.2-only patch would go over. Any advice on that point? -- Gwynne, Daughter of the Code "This whole world is an asylum for the incurable."

Matt W

20 years ago
Hi Gwynne, ----- Original Message ----- From: "Gwynne" Sent: Sunday, July 23, 2006
> On Jul 23, 2006, at 5:38 AM, Matt W wrote: > >> While we're on the subject, one of my favorite personal patches to > >> PHP is one that adds the %n specifier. The parameter to %n is a > >> reference which recieves the total length of the string with all > >> replacements so far. %n itself is replaced by nothing at all. You > >> could do this with $n = strlen( $s = sprintf( blah blah blah ) ) + > >> strlen( $s .= sprintf( the rest of the blah ) );, but it's a very > >> nice shortcut if you need the replaced length in the middle of the > >> conversion or for a situation like this (and the above doesn't work > >> too well if you have positional params!): > >> > >> printf( "Some processing message with %s replacements...%n", > >> 'some', & > >> $n ); > >> // do some stuff here > >> print str_repeat( ' ', $n ) . "\rSome status text here that doesn't > >> worry about whether the replaced text was longer."; > >> > >> Here's the printf(3) manpage description for %n (MacOS X system, BSD > >> manpage): > >> > >> n The number of characters written so far is stored into > >> the inte- > >> ger indicated by the int * (or variant) pointer > >> argument. No > >> argument is converted. > >> > >> Any chance of getting this into PHP? I can provide a patch. > > I had thought about adding %n too, but didn't know what the > > reaction would > > be or if it'd be used. (And the length thing would have to be changed > > [later] for Unicode length or such, I assume?) Also, wasn't sure > > about the > > internals code for the reference and writing to it, etc. :-) > > I'm completely unversed in the current Unicode stuff; I can only > provide a patch against 5.2. Someone who knows the Unicode crud would > have to update it for HEAD, and given the recent loud argument about > HEAD vs branch commits, I don't know how well a 5.2-only patch would > go over. Any advice on that point?
The formatted_print.c code is currently the same for both versions, so I'd submit the patch for both. Not to dump the work on someone else then, but I'm pretty sure the existing code will need updating for Unicode, and I think updating the %n length stuff would be a fairly simple thing overall. :-) Matt