Issue2802
This issue tracker has been migrated to GitHub,
and is currently read-only.
For more information,
see the GitHub FAQs in the Python's Developer Guide.
Created on 2008-05-09 14:08 by mark, last changed 2022-04-11 14:56 by admin. This issue is now closed.
Messages (9) | |||
---|---|---|---|
msg66471 - (view) | Author: Mark Summerfield (mark) * | Date: 2008-05-09 14:07 | |
In Py30a5 the 'n' format option is not v. useful for integers: >>> for x in range(8): print("{0:n} ".format(10**x), end="") 1 10 100 1,000 10,000 100,000 1e+06 1e+07 This is because it behaves like g once a number grows large. That makes sense for floats, but since Python has unlimited size integers there is currently no built-in way to get, 10**6 to output as 1,000,000 (or using whatever the user's locale-dependent separator is). (It is easy to write a suitable function for this, but it just seems that n is a bit of a teaser in this regard.) I think that n should stay the same for floats, but for integers should never switch to g, but just use as many separators as needed. |
|||
msg66472 - (view) | Author: Mark Dickinson (mark.dickinson) * | Date: 2008-05-09 14:23 | |
> I think that n should stay the same for floats, but for integers should > never switch to g, but just use as many separators as needed. I agree with this, in principle. It might be some work to implement, though: for floats, Python gets to use the OS-supplied formatting functions. Indeed, it looks as though all that happens here is that the integer is converted to a float before formatting: >>> print("{0:n} ".format(10**400), end="") Traceback (most recent call last): File "<stdin>", line 1, in <module> OverflowError: Python int too large to convert to C double For integers, we'd have to roll our own code. I had similar problems trying to implement the 'n' format code for Decimal; in the end I just gave up and left it unimplemented. Maybe using 'n' for an integer should just raise an exception, for now? Eric, what do you think? |
|||
msg66474 - (view) | Author: Eric V. Smith (eric.smith) * | Date: 2008-05-09 14:42 | |
The reason for this is that 'n' is defined in PEP 3101 as being a float format only, and the rule is that if an integer sees a float format, it does a float conversion and then prints the float with the supplied format. I'd be okay with adding 'n' as an integer format, with the loose definition of "just like 'd', but adding thousands separators". As to the implementation, the OS supplied float formatting does not add thousands separators. I added the function add_thousands_grouping() to Python/pystrtod.c in order implement this for floats. It would be easy to make this same code work for integers (and in fact it might already work, although there are probably memory allocation issues to deal with). Maybe we should bring up modifying the PEP on python-dev or python-3000. This issue exists in 2.6 as well. |
|||
msg66475 - (view) | Author: Mark Summerfield (mark) * | Date: 2008-05-09 14:44 | |
On 2008-05-09, Mark Dickinson wrote: > Mark Dickinson <dickinsm@gmail.com> added the comment: > > I think that n should stay the same for floats, but for integers should > > never switch to g, but just use as many separators as needed. > > I agree with this, in principle. It might be some work to implement, > though: for floats, Python gets to use the OS-supplied formatting > functions. Indeed, it looks as though all that happens here is that the > > integer is converted to a float before formatting: > >>> print("{0:n} ".format(10**400), end="") > > Traceback (most recent call last): > File "<stdin>", line 1, in <module> > OverflowError: Python int too large to convert to C double > > For integers, we'd have to roll our own code. I had similar problems > trying to implement the 'n' format code for Decimal; in the end I just > gave up and left it unimplemented. Maybe using 'n' for an integer should > just raise an exception, for now? > > Eric, what do you think? It isn't hard (in Python): import locale locale.setlocale(locale.LC_ALL, "") separator = locale.localeconv()["thousands_sep"] def n_format(integer, separator): chars = [] for i, char in enumerate(reversed("{0:d}".format(integer))): if i and not i % 3: chars.insert(0, separator) chars.insert(0, char) return "".join(chars) |
|||
msg66477 - (view) | Author: Eric V. Smith (eric.smith) * | Date: 2008-05-09 14:55 | |
> It isn't hard (in Python): <code deleted> It's more complex, because the "3" is locale dependent, and is allowed to be something like "3, then 2, then 3, then 1, repeating until the start of the string". See _group() in Lib/locale.py. In any event, the code needs to be in C (sadly). But as I said in my previous comment (which probably crossed paths with yours), this C code already exists. |
|||
msg66478 - (view) | Author: Mark Summerfield (mark) * | Date: 2008-05-09 14:55 | |
On 2008-05-09, Eric Smith wrote: > Eric Smith <eric@trueblade.com> added the comment: > > The reason for this is that 'n' is defined in PEP 3101 as being a float > format only, and the rule is that if an integer sees a float format, it > does a float conversion and then prints the float with the supplied format. > > I'd be okay with adding 'n' as an integer format, with the loose > definition of "just like 'd', but adding thousands separators". > > As to the implementation, the OS supplied float formatting does not add > thousands separators. I added the function add_thousands_grouping() to > Python/pystrtod.c in order implement this for floats. It would be easy > to make this same code work for integers (and in fact it might already > work, although there are probably memory allocation issues to deal with). > > Maybe we should bring up modifying the PEP on python-dev or python-3000. I hope that you do:-) > This issue exists in 2.6 as well. > > ---------- > components: +Interpreter Core > versions: +Python 2.6 > > __________________________________ > Tracker <report@bugs.python.org> > <http://bugs.python.org/issue2802> > __________________________________ |
|||
msg66479 - (view) | Author: Mark Dickinson (mark.dickinson) * | Date: 2008-05-09 15:12 | |
> As to the implementation, the OS supplied float formatting does not add > thousands separators. I added the function add_thousands_grouping() to > Python/pystrtod.c in order implement this for floats. Excellent! I didn't realise this code was already there. Maybe there's also some way to use it to implement 'n' formatting for Decimal (which in some ways behaves like a hybrid floating-point and integer type). I can't think of any reason that the LC_NUMERIC stuff shouldn't apply to integers as well as floats. |
|||
msg66659 - (view) | Author: Eric V. Smith (eric.smith) * | Date: 2008-05-11 19:53 | |
Implemented in 2.6 as r63078. I'll port this to py3k shortly. |
|||
msg66671 - (view) | Author: Eric V. Smith (eric.smith) * | Date: 2008-05-11 21:17 | |
Implemented in 3.0 as r63093. I'm closing this issue. I added the C code that does the grouping insertion as _PyString_InsertThousandsGrouping and _PyUnicode_InsertThousandsGrouping (in 3.0). This might be useful to others, although the API is fairly complicated. Mark Dickinson: For Decimal, you can probably get what you need from Lib/locale.py, although the function _group() is private. |
History | |||
---|---|---|---|
Date | User | Action | Args |
2022-04-11 14:56:34 | admin | set | github: 47051 |
2008-05-11 21:17:56 | eric.smith | set | status: open -> closed resolution: fixed messages: + msg66671 |
2008-05-11 19:53:57 | eric.smith | set | messages: + msg66659 |
2008-05-09 15:12:02 | mark.dickinson | set | messages: + msg66479 |
2008-05-09 14:55:33 | mark | set | messages: + msg66478 |
2008-05-09 14:55:01 | eric.smith | set | messages: + msg66477 |
2008-05-09 14:44:15 | mark | set | messages: + msg66475 |
2008-05-09 14:42:20 | eric.smith | set | messages:
+ msg66474 components: + Interpreter Core versions: + Python 2.6 |
2008-05-09 14:23:28 | mark.dickinson | set | priority: normal assignee: eric.smith messages: + msg66472 nosy: + mark.dickinson, eric.smith |
2008-05-09 14:08:07 | mark | create |