Skip to content

math.log, log10 inconsistency #51014

Closed
Closed

Description

@steve21
mannequin
BPO 6765
Nosy @tim-one, @birkenfeld, @terryjreedy, @mdickinson

Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.

Show more details

GitHub fields:

assignee = 'https://github.com/birkenfeld'
closed_at = <Date 2009-09-01.07:54:00.726>
created_at = <Date 2009-08-23.11:56:16.284>
labels = ['docs']
title = 'math.log, log10 inconsistency'
updated_at = <Date 2009-09-01.07:54:00.724>
user = 'https://bugs.python.org/steve21'

bugs.python.org fields:

activity = <Date 2009-09-01.07:54:00.724>
actor = 'georg.brandl'
assignee = 'georg.brandl'
closed = True
closed_date = <Date 2009-09-01.07:54:00.726>
closer = 'georg.brandl'
components = ['Documentation']
creation = <Date 2009-08-23.11:56:16.284>
creator = 'steve21'
dependencies = []
files = []
hgrepos = []
issue_num = 6765
keywords = []
message_count = 7.0
messages = ['91886', '91888', '91900', '91918', '91919', '92042', '92126']
nosy_count = 5.0
nosy_names = ['tim.peters', 'georg.brandl', 'terry.reedy', 'mark.dickinson', 'steve21']
pr_nums = []
priority = 'normal'
resolution = 'fixed'
stage = None
status = 'closed'
superseder = None
type = None
url = 'https://bugs.python.org/issue6765'
versions = ['Python 2.6', 'Python 3.1', 'Python 2.7', 'Python 3.2']

Activity

  1. steve21 commented on Aug 23, 2009

    steve21mannequin
    MannequinAuthor
    $ python3.1
    Python 3.1 (r31:73572, Jul  6 2009, 21:21:12) 
    [GCC 4.4.0 20090506 (Red Hat 4.4.0-4)] on linux2
    Type "help", "copyright", "credits" or "license" for more information.
    >>> import math
    >>> math.log10(1000)
    3.0
    >>> math.log(1000, 10)
    2.9999999999999996

    You would expect the results to be the same.
    Internally math.log() could call math.log10() when base==10. That would
    ensure they are consistent.

  2. added
    stdlibStandard Library Python modules in the Lib/ directory
    on Aug 23, 2009
  3. mdickinson commented on Aug 23, 2009

    @mdickinson
    Member

    Well, that's floating-point arithmetic for you. log(x, y) simply computes
    log(x)/log(y) behind the scenes; since both log computations and the
    floating-point division can introduce errors, the result will frequently
    not be correctly rounded.

    I don't really see the benefit of special-casing log(x, 10). In what
    circumstances does it matter that log(x, 10) != log10(x)? I could
    understand people being upset that log(10**n, 10) doesn't return n
    exactly, but that's what log10 is there for.

    See also the discussion in bpo-3724.

  4. steve21 commented on Aug 24, 2009

    steve21mannequin
    MannequinAuthor

    Mark,
    "... that's what log10 is there for". That would be a good point if the
    documentation said that. However, all the docs for log10 say is:

    math.log10(x)
        Return the base-10 logarithm of x.

    So we have a python function log10() which looks like it is redundant
    since we can use log(a, 10) instead. But it actually functions
    differently to log(a, 10), and the Python user would never know this
    from looking at the documentation.

    I think Tim Peters missed one important guideline in his "The Zen of
    Python". The principle of least astonishment (or surprise) - when two
    elements of an interface conflict, or are ambiguous, the behaviour
    should be that which will least surprise the human user or programmer at
    the time the conflict arises.

    Its easy for the python developer to ignore this guideline. They know
    the implementation, and are rarely surprised by inconsistent behaviour
    since they have seen it before, or even created it without documenting it.

    If Python functions are inconsistent then I think they should either be
    made consistent, or if that's not possible they should be clearly
    documented as being inconsistent.

    The docs for log(x[, base]) could be improved to say:
    "this function preserves the consistency of log(a,b) == log(a)/log(b)
    but breaks consistency with log(a,10) == log10(a)"

    The docs for log10(x) could be improved to say:
    "this function gives the correct result for powers of 10,
    but breaks consistency with log(a,10) == log10(a)"

  5. mdickinson commented on Aug 24, 2009

    @mdickinson
    Member

    If Python functions are inconsistent then I think they should either
    be
    made consistent, or if that's not possible they should be clearly
    documented as being inconsistent.

    I think 'inconsistent' is a bit strong for what happens here. In my
    view, the expressions log10(x) and log(x, 10) behave consistently: they
    both give (good) floating-point approximations to the base-10 logarithm
    of x. However, since they use slightly different methods to get those
    approximations, the approximations are not identical.

    Would you also say that atan2(y, x) is inconsistent with atan(y/x) (for
    positive x, y, say), because they give minutely different results in
    some cases?

    The docs for log10(x) could be improved to say:
    "this function gives the correct result for powers of 10,
    but breaks consistency with log(a,10) == log10(a)"

    I find this unnecessarily negative. I propose instead to leave the log
    documentation as it is, and add something like the following to the
    log10 documentation, as an explanation of why log10 is still valuable in
    the presence of the two-argument log function:

    """Since this function directly wraps the platform log10 function,
    log10(x) will usually (depending on the platform) be faster and more
    accurate than the mathematically equivalent log(x, 10)."""

    Note that historically, the two-argument version of math.log appeared
    long after math.log10 did; this might help explain the apparent
    redundancy. (I'd actually argue that the two-argument log should not
    have been added in the first place: it doesn't wrap a standard C math
    function, and it's really no different from log(x)/log(y), except that
    having it as a built-in library function gives the illusion that it
    might be more accurate than it actually is. However, that's academic
    now.)

    One possible 'fix' for this situation does occur to me: instead of
    computing log(x, y) internally as log(x)/log(y), compute it as
    log10(x)/log10(y). This at least doesn't involve extensive changes or
    additions to the code. I don't think it really makes any practical
    difference, except perhaps in reducing the number of bug reports like
    this one. And it won't help make log2(x) == log(x, 2) if/when the C99
    log2 function is added to the math library, either. I'd be -0 on making
    this change.

  6. tim-one commented on Aug 24, 2009

    @tim-one
    Member

    I wasn't keen to add the 2-argument log() extension either. However, I
    bet it would help if the docs for that were changed to explain that
    log(x, base) is just a convenient shorthand for computing
    log(x)/log(base), and therefore may be a little less accurate than a
    function that directly computed the logarithm wrt the given base.

  7. terryjreedy commented on Aug 28, 2009

    @terryjreedy
    Member

    Reopening as doc issue. This is at least the second time this issue has
    been reported (see bpo-3724), with some agreement on doc tweak, but not done.

    Specific suggestions for math module doc, 9.2.2:

    math.log(x[, base]) 
    Return the logarithm of x to the given base. 

    add: ", calculated as log(x)/log(base)" before period.

    [This could be removed if better method ever implemented.]

    math.log10(x) 
    Return the base-10 logarithm of x.

    add: "This is usually more accurate than log(x, 10)."

  8. added
    docsDocumentation in the Doc dir
    and removed
    stdlibStandard Library Python modules in the Lib/ directory
    on Aug 28, 2009
  9. birkenfeld commented on Sep 1, 2009

    @birkenfeld
    Member

    Okay, I made changes along Terry' suggestions in r74617.

  10. transferred this issue fromon Apr 10, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

docsDocumentation in the Doc dir

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions