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 2013年12月09日 04:24 by JBernardo, last changed 2022年04月11日 14:57 by admin. This issue is now closed.
| Files | ||||
|---|---|---|---|---|
| File name | Uploaded | Description | Edit | |
| fix_round_with_zero_ndigits.patch | vajrasky, 2013年12月09日 06:52 | review | ||
| fix_doc_round_ndigits.patch | vajrasky, 2013年12月09日 08:58 | review | ||
| fix_doc_round_ndigits_v2.patch | vajrasky, 2013年12月09日 14:55 | review | ||
| fix_doc_ndigits_round_and_add_None_ndigits.patch | vajrasky, 2013年12月10日 04:42 | review | ||
| Messages (17) | |||
|---|---|---|---|
| msg205647 - (view) | Author: João Bernardo (JBernardo) * | Date: 2013年12月09日 04:24 | |
From the docs for built-in function "round": "If ndigits is omitted, it defaults to zero" (http://docs.python.org/3/library/functions.html#round) But, the only way to get an integer from `round` is by not having the second argument (ndigits): >>> round(3.5) 4 >>> round(3.5, 1) 3.5 >>> round(3.5, 0) 4.0 >>> round(3.5, -1) 0.0 >>> round(3.5, None) Traceback (most recent call last): File "<pyshell#6>", line 1, in <module> round(3.5, None) TypeError: 'NoneType' object cannot be interpreted as an integer Either the docs are wrong or the behavior is wrong. I think it's easier to fix the former... But also there should be a way to make round return an integer (e.g. passing `None` as 2nd argument) |
|||
| msg205650 - (view) | Author: Vajrasky Kok (vajrasky) * | Date: 2013年12月09日 06:52 | |
Here is the preliminary patch. After patch: round(1.23, 0) => 1 not 1.0 round(4.67, 0) => 5 not 5.0 |
|||
| msg205651 - (view) | Author: Mark Dickinson (mark.dickinson) * (Python committer) | Date: 2013年12月09日 08:30 | |
> After patch: > round(1.23, 0) => 1 not 1.0 > round(4.67, 0) => 5 not 5.0 Please no! Two-argument round should continue to return a float in all cases. The docs should be fixed. |
|||
| msg205652 - (view) | Author: Mark Dickinson (mark.dickinson) * (Python committer) | Date: 2013年12月09日 08:32 | |
> But also there should be a way to make round return an integer I don't understand. There's already a way to make round return an integer: don't pass a second argument. |
|||
| msg205653 - (view) | Author: Vajrasky Kok (vajrasky) * | Date: 2013年12月09日 08:56 | |
Okay, here is the patch to fix the doc. |
|||
| msg205682 - (view) | Author: Mark Dickinson (mark.dickinson) * (Python committer) | Date: 2013年12月09日 12:04 | |
Thanks. It's inaccurate to say that a float is returned in general, though: for most builtin numeric types, what's returned has the same type as its input. So rounding a Decimal to two places gives a Decimal on output, etc. (That's already explained in the next paragraph.) |
|||
| msg205683 - (view) | Author: Mark Dickinson (mark.dickinson) * (Python committer) | Date: 2013年12月09日 12:06 | |
How about just removing the mention of 'defaults to zero', and say something like: "if ndigits is omitted, returns the nearest int to its input" |
|||
| msg205695 - (view) | Author: João Bernardo (JBernardo) * | Date: 2013年12月09日 14:14 | |
> I don't understand. There's already a way to make round return an integer: don't pass a second argument. If this function were to be written in Python, it would be something like: def round(number, ndigits=0): ... or def round(number, ndigits=None): ... But in C you can forge the signature to whatever you want and parse the arguments accordingly. In Python there's always a way to get the default behavior by passing the default argument, but in C it may not exist (in this case `PyObject *o_ndigits = NULL;`) So, I propose the default value being `None`, so this behavior can be achieved using a second argument. |
|||
| msg205699 - (view) | Author: Vajrasky Kok (vajrasky) * | Date: 2013年12月09日 14:55 | |
Here is the updated doc fix. Anyway, why not round(1.2) -> 1.0 in the first place? Just curious. |
|||
| msg205703 - (view) | Author: João Bernardo (JBernardo) * | Date: 2013年12月09日 15:25 | |
> Anyway, why not round(1.2) -> 1.0 in the first place? Just curious. It was the behavior on Python 2.x, but somehow when they changed the rounding method to nearest even number this happened... I think it's too late to change back the return type. |
|||
| msg205704 - (view) | Author: R. David Murray (r.david.murray) * (Python committer) | Date: 2013年12月09日 15:31 | |
Do you have any real-world motivating use case for None? Not just theoretical consistency with what a Python version of the function would look like. (I'm not saying we shouldn't consider supporting None as a low priority change, I'm just trying to figure out where you'd ever need it in the real world.) |
|||
| msg205706 - (view) | Author: João Bernardo (JBernardo) * | Date: 2013年12月09日 15:44 | |
Not really. Just consistency: For the same reason ' foo '.strip(None) works... To avoid special casing the function call when you already have a variable to hold the argument. |
|||
| msg205708 - (view) | Author: R. David Murray (r.david.murray) * (Python committer) | Date: 2013年12月09日 16:06 | |
Right, but None in that case has real world utility, since you might have the the value in a variable. But you are hardly going to hold int-or-not in a variable, especially a variable that is really about the number of places in the float result... |
|||
| msg205729 - (view) | Author: Mark Dickinson (mark.dickinson) * (Python committer) | Date: 2013年12月09日 19:07 | |
> Anyway, why not round(1.2) -> 1.0 in the first place? Just curious. All this changed as part of PEP 3141. I wasn't watching Python 3 development closely back then, but I *think* at least part of the motivation was to provide a way to get away from the use of `int` to truncate a float to its integer part: the argument goes that a simple type conversion shouldn't throw away information, and that if you want a transformation from float to int that throws away information you should ask for it explicitly. So `math.trunc` was born as the preferred way to truncate a float to an int, and `math.floor`, `math.ceil` and `round` became alternative float -> int conversion methods. That entailed those functions returning ints. <off-topic> In the case of `math.floor` and `math.ceil` at least, I think this is regrettable. There are plenty of places where you just want a float -> float floor or ceiling, and Python no longer has a cheap operation for that available: floor as a float-to-float operation is cheap; floor as a float-to-long-integer operation is significantly more costly. In the case of `round`, we still have `round(x, 0)` available as a cheap float->float conversion, so it's less of a problem. And I hardly ever use `trunc`, so I don't care about that case. </off-topic> |
|||
| msg205770 - (view) | Author: Vajrasky Kok (vajrasky) * | Date: 2013年12月10日 04:42 | |
In case we want to add consistency with None ndigits, here is the patch adding support for None value for ndigits parameter. This one looks like a low-risk addition but since Python 3.4 is in beta phase.... |
|||
| msg206162 - (view) | Author: Terry J. Reedy (terry.reedy) * (Python committer) | Date: 2013年12月14日 02:18 | |
The docstring is better than the current doc as it says that the default precision is 0, without calling that the default for ndigits.
''' round(number[, ndigits]) -> number
Round a number to a given precision in decimal digits (default 0 digits).
This returns an int when called with one argument, otherwise the
same type as the number. ndigits may be negative.'''
---
Sidenote: To write round in Python, one could easily write
_sentinel = object
def round(number, ndigits=_sentinel):
if ndigits is _sentinel: ...
which makes ndigits positional-or-keyword, and almost optional-with-no-default, as _sentinel is close enough to being a default that cannot be passed in. This is a standard idiom. One who was really picky about having no default could use
def round(number, *args, **kwds): ...
and look for len(args) == 1 xor kwds.keys() == {'ndigits'}.
|
|||
| msg241152 - (view) | Author: Roundup Robot (python-dev) (Python triager) | Date: 2015年04月15日 20:16 | |
New changeset e3cc75b1000b by Steve Dower in branch 'default': Issue 19933: Provide default argument for ndigits in round. Patch by Vajrasky Kok. https://hg.python.org/cpython/rev/e3cc75b1000b |
|||
| History | |||
|---|---|---|---|
| Date | User | Action | Args |
| 2022年04月11日 14:57:55 | admin | set | github: 64132 |
| 2015年04月15日 20:16:44 | steve.dower | set | status: open -> closed resolution: fixed versions: + Python 3.5, - Python 3.4 |
| 2015年04月15日 20:16:20 | python-dev | set | nosy:
+ python-dev messages: + msg241152 |
| 2013年12月14日 02:18:07 | terry.reedy | set | nosy:
+ terry.reedy messages: + msg206162 |
| 2013年12月10日 04:42:34 | vajrasky | set | files:
+ fix_doc_ndigits_round_and_add_None_ndigits.patch messages: + msg205770 |
| 2013年12月09日 19:07:00 | mark.dickinson | set | messages: + msg205729 |
| 2013年12月09日 16:06:47 | r.david.murray | set | messages: + msg205708 |
| 2013年12月09日 15:44:54 | JBernardo | set | messages: + msg205706 |
| 2013年12月09日 15:31:59 | r.david.murray | set | nosy:
+ r.david.murray messages: + msg205704 |
| 2013年12月09日 15:25:04 | JBernardo | set | messages: + msg205703 |
| 2013年12月09日 14:55:18 | vajrasky | set | files:
+ fix_doc_round_ndigits_v2.patch messages: + msg205699 |
| 2013年12月09日 14:14:09 | JBernardo | set | messages: + msg205695 |
| 2013年12月09日 12:06:37 | mark.dickinson | set | messages: + msg205683 |
| 2013年12月09日 12:04:29 | mark.dickinson | set | messages: + msg205682 |
| 2013年12月09日 08:58:06 | vajrasky | set | files: + fix_doc_round_ndigits.patch |
| 2013年12月09日 08:57:58 | vajrasky | set | files: - fix_doc_round_ndigits.patch |
| 2013年12月09日 08:57:22 | vajrasky | set | files: + fix_doc_round_ndigits.patch |
| 2013年12月09日 08:57:09 | vajrasky | set | files: - fix_doc_round_ndigits.patch |
| 2013年12月09日 08:56:39 | vajrasky | set | files:
+ fix_doc_round_ndigits.patch messages: + msg205653 |
| 2013年12月09日 08:32:07 | mark.dickinson | set | messages: + msg205652 |
| 2013年12月09日 08:30:47 | mark.dickinson | set | messages: + msg205651 |
| 2013年12月09日 06:53:13 | vajrasky | set | nosy:
+ mark.dickinson |
| 2013年12月09日 06:52:30 | vajrasky | set | files:
+ fix_round_with_zero_ndigits.patch nosy: + vajrasky messages: + msg205650 keywords: + patch |
| 2013年12月09日 04:24:20 | JBernardo | create | |