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

- Thread: https://externals.io/message/24760
- Original archive: https://news-web.php.net/php.internals/24760
- Started by Matt W on 2006-07-20T12:20:46+00:00
- Messages: 10
- Reply by email to internals@lists.php.net
- More for agents: search with https://externals.io/search.md?q={query} · JSON API at https://externals.io/api · documentation at https://externals.io/llms.txt

---

## #24760 — Matt W — 2006-07-20T12:20:46+00:00

URL: https://externals.io/message/24760#24760

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

---

## #24772 — Marcus Boerger — 2006-07-20T19:21:12+00:00

URL: https://externals.io/message/24760#24772 · In reply to: #24760

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

---

## #24803 — Matt W — 2006-07-21T08:08:19+00:00

URL: https://externals.io/message/24760#24803 · In reply to: #24772

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:
>
> > […]
>
> > […]
can
> > […]
want
> > […]
then I
> > […]
"not
> > […]
>
> > […]
E
> > […]
used
> > […]
behavior
> > […]
>
> 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

---

## #24847 — Marcus Boerger — 2006-07-21T17:14:53+00:00

URL: https://externals.io/message/24760#24847 · In reply to: #24803

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)


> > […]
> can
> > […]
> want
> > […]
> then I
> > […]
> "not
> > […]
> E
> > […]
> used
> > […]
> behavior
> > […]

> 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!

> > […]

> Thanks for the reply,
> Matt




Best regards,
 Marcus

---

## #24872 — Matt W — 2006-07-22T07:15:04+00:00

URL: https://externals.io/message/24760#24872 · In reply to: #24847

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:
>
> > […]
>
> > […]
>
> > […]
opposite
> > […]
>
> > […]
additions
> > […]
nor
> > […]
let #
> > […]
>
> > […]
if 1)
> > […]
than
> > […]
>
> > […]
>
> > […]
trailing
> > […]
would
> > […]
>
> > […]
>
> > […]

---

## #24883 — Gwynne — 2006-07-22T18:44:34+00:00

URL: https://externals.io/message/24760#24883 · In reply to: #24772

> > […]
>
> > […]
> 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."

---

## #24900 — Matt W — 2006-07-23T09:38:57+00:00

URL: https://externals.io/message/24760#24900 · In reply to: #24883

Hi Gwynne,

----- Original Message ----- 
From: "Gwynne"
Sent: Saturday, July 22, 2006


> 
> > […]
>
> 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

---

## #24915 — Gwynne — 2006-07-24T01:00:06+00:00

URL: https://externals.io/message/24760#24915 · In reply to: #24900

> > […]
> 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."

---

## #24921 — Matt W — 2006-07-24T08:12:53+00:00

URL: https://externals.io/message/24760#24921 · In reply to: #24915

Hi Gwynne,

----- Original Message ----- 
From: "Gwynne"
Sent: Sunday, July 23, 2006


> 
> > […]
>
> 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

---

## #25175 — Matt W — 2006-08-03T09:20:54+00:00

URL: https://externals.io/message/24760#25175 · In reply to: #24847

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:
>
> > […]
>
> > […]
>
>
> > […]
include
> > […]
was
> > […]
and
> > […]
(I
> > […]
opposite
> > […]
>
> > […]
additions
> > […]
nor
> > […]
let #
> > […]
>
> > […]
if 1)
> > […]
than
> > […]
>
> > […]
>
> > […]
trailing
> > […]
would
> > […]
>
> > […]
>
> > […]
