Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

math.log(x, 10) gives different result than math.log10(x) #47974

Closed
segfaulthunter mannequin opened this issue Aug 29, 2008 · 12 comments
Closed

math.log(x, 10) gives different result than math.log10(x) #47974

segfaulthunter mannequin opened this issue Aug 29, 2008 · 12 comments
Assignees
Labels
type-bug An unexpected behavior, bug, or error

Comments

@segfaulthunter
Copy link
Mannequin

segfaulthunter mannequin commented Aug 29, 2008

BPO 3724
Nosy @rhettinger, @terryjreedy, @mdickinson, @vstinner
Files
  • log.patch: Internally use math.log10 when math.log gets the base 10 to improve accuracy and performance.
  • math_doc.patch: Documentation tweak.
  • 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/mdickinson'
    closed_at = <Date 2008-12-05.21:47:35.319>
    created_at = <Date 2008-08-29.12:32:07.135>
    labels = ['type-bug']
    title = 'math.log(x, 10) gives different result than math.log10(x)'
    updated_at = <Date 2009-09-01.09:58:50.177>
    user = 'https://bugs.python.org/segfaulthunter'

    bugs.python.org fields:

    activity = <Date 2009-09-01.09:58:50.177>
    actor = 'terry.reedy'
    assignee = 'mark.dickinson'
    closed = True
    closed_date = <Date 2008-12-05.21:47:35.319>
    closer = 'mark.dickinson'
    components = []
    creation = <Date 2008-08-29.12:32:07.135>
    creator = 'segfaulthunter'
    dependencies = []
    files = ['11310', '11362']
    hgrepos = []
    issue_num = 3724
    keywords = ['patch']
    message_count = 12.0
    messages = ['72129', '72389', '72398', '72423', '74349', '74578', '74584', '74630', '74734', '74738', '77077', '92139']
    nosy_count = 5.0
    nosy_names = ['rhettinger', 'terry.reedy', 'mark.dickinson', 'vstinner', 'segfaulthunter']
    pr_nums = []
    priority = 'normal'
    resolution = 'rejected'
    stage = None
    status = 'closed'
    superseder = None
    type = 'behavior'
    url = 'https://bugs.python.org/issue3724'
    versions = ['Python 2.6']

    @segfaulthunter
    Copy link
    Mannequin Author

    segfaulthunter mannequin commented Aug 29, 2008

    I have found out that the result of math.log(x, 10) is slightly more
    inaccurate than the one of math.log10(x). Probably the best example is
    math.log(1000, 10) and math.log10(1000). I have attached a patch that
    forces math.log to internally use log10 when it gets the base 10. Patch
    is against revision 66056. Also adds 3 tests to test_math.py to test new
    behaviour implemented.

    @segfaulthunter segfaulthunter mannequin added the type-bug An unexpected behavior, bug, or error label Aug 29, 2008
    @mdickinson
    Copy link
    Member

    I can't really see a compelling reason to make this change---it
    seems like an unnecessary complication to add to what's currently
    a simple function. Someone who really needs the accuracy can
    just use log10. Perhaps a note in the documentation for log
    suggesting this would be useful.

    I guess this solution seems insufficiently general: why 'fix'
    log(x, 10) but not log(x, 2), for example?

    OTOH, a two-argument log that was guaranteed correctly rounded
    (or accurate to within 1ulp) for *all* bases would certainly
    be of interest! But that's a fairly major project...

    @rhettinger
    Copy link
    Contributor

    Mark, thanks for the first review comments. Am also disturbed by the
    lack of generality and don't think it wise to introduce a discontinuity.
    Am rejecting this patch. Leaving the bug report open in case other
    solutions arise.

    @segfaulthunter
    Copy link
    Mannequin Author

    segfaulthunter mannequin commented Sep 3, 2008

    Uploaded small documentation patch warning the user of math.log(x, 10)
    inaccuracy.

    @rhettinger rhettinger assigned rhettinger and unassigned mdickinson Sep 3, 2008
    @rhettinger
    Copy link
    Contributor

    Mark, is some of the inaccuracy due to double rounding? Could we make
    the two argument form more accurate by allowing the compiler to generate
    code that uses full internal precision, log(n)/log(d), instead of
    prematurely forcing the intermediate results to a PyFloat?

    @rhettinger rhettinger assigned mdickinson and unassigned rhettinger Oct 5, 2008
    @mdickinson
    Copy link
    Member

    Mark, is some of the inaccuracy due to double rounding?

    No, I don't think so; at least, not in the sense of rounding the same
    value twice (with different precisions). I get similar results on my
    Core 2 Duo machine, which should be immune to x87 style problems
    (because Apple's gcc turns sse instructions on by default, I guess).
    It's just a result of three separate rounds: one for each log, and one
    for the result of the division.

    Could we make the two argument form more accurate by allowing the
    compiler to generate code that uses full internal precision,
    log(n)/log(d), instead of prematurely forcing the intermediate results
    to a PyFloat?

    Seems to me that would only work on older x86 hardware, unless we
    deliberately use long double in place of double for the intermediate
    results.

    Personally, I don't think it's worth the effort of fixing this: the
    result of log(x, 10) is accurate to within a few ulps anyway, which
    should be plenty good enough for any well-coded numerical work: any
    numerically aware programmer should be well aware that it's dangerous to
    rely on floating-point operations giving exact results.

    And in any case there's always log10.

    As a separate issue, it may be worth exposing C99's log2 function in
    some future version of Python. This, presumably, can be relied upon
    always to give exact results for powers of 2, which could be useful in
    some applications.

    @rhettinger
    Copy link
    Contributor

    +1 on a log2 function, especially one that has been generalized to work
    with long integers. It would help with the "numbits" problem that
    comes-up all the time.

    @vstinner
    Copy link
    Member

    About large integers which can not be converted to float (too big!):
    it would be nice if math.log2() and/or math.log10() works which such
    numbers. But it would better if you know if the functions used the FPU
    or not (only integers). Idea:

    • logX(int)->int: don't use FPU
    • logX(float)->float: use FPU
    • logX(int)->float: use FPU

    What should be the default type for logX(int)? People expects float
    when using logX().

    Note: logX() means math.log(), math.log2() and/or math.log10().

    @mdickinson
    Copy link
    Member

    Note that log2(int) -> float wouldn't entirely replace
    numbits, due to loss of precision in the result.

    e.g. log2(2**100), log2(2**100+1) and log2(2**100-1) would likely all
    return exactly the same result (100.0), where numbits wants results of
    101, 101 and 100 respectively.

    @vstinner
    Copy link
    Member

    About the number of bits: I prefer an the implementation in int/long
    types proposed in issue bpo-3439.

    @mdickinson
    Copy link
    Member

    I'm closing this, for reasons already given.

    For the proposal to add log2, see bpo-3366.

    @terryjreedy
    Copy link
    Member

    The docs were patched in r74617 to (re)close bpo-6765.
    This included something similar to the OP's math_doc.patch.

    @ezio-melotti ezio-melotti transferred this issue from another repository Apr 10, 2022
    Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
    Labels
    type-bug An unexpected behavior, bug, or error
    Projects
    None yet
    Development

    No branches or pull requests

    4 participants