[issue9959] int(math.log(4,2)) == 1 instead of 2

2010-09-29 Thread Mark Dickinson

Mark Dickinson dicki...@gmail.com added the comment:

Applied further tweaks in r85120:  for an integer n, log(n) is now computed as 
log(float(n)), provided only that n is small enough to be converted to a float 
without overflow.  This puts log on a more equal footing with all the other 
math module functions, and satisfies the (reasonable, IMO) expectation that 
log(n) == log(float(n)) for small integers n.

As a nice side-effect, this change guarantees that on a machine where log10 has 
reasonable accuracy (e.g., accurate to within 0.9 ulps or so), log10(10**n)==n 
for any nonnegative integer n such that 10**n is within the range of a double.

--

___
Python tracker rep...@bugs.python.org
http://bugs.python.org/issue9959
___
___
Python-bugs-list mailing list
Unsubscribe: 
http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue9959] int(math.log(4,2)) == 1 instead of 2

2010-09-28 Thread Mark Dickinson

Mark Dickinson dicki...@gmail.com added the comment:

I've tweaked the loghelper algorithm in r85048.

Looking at [n for n in range(100) if log(2**n) != n], I get:

Python 3.1:  14 bad values out of 1st 100;  first is 29
Python 3.2 (patched): 10 bad values;  first is 29
Python 3.2 (unpatched): 25 bad values; first is 2.

--
resolution:  - fixed
status: open - closed

___
Python tracker rep...@bugs.python.org
http://bugs.python.org/issue9959
___
___
Python-bugs-list mailing list
Unsubscribe: 
http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue9959] int(math.log(4,2)) == 1 instead of 2

2010-09-28 Thread Mark Dickinson

Mark Dickinson dicki...@gmail.com added the comment:

 [n for n in range(100) if log(2**n) != n]

Should be:

[n for n in range(100) if log(2**n, 2) != n]

--

___
Python tracker rep...@bugs.python.org
http://bugs.python.org/issue9959
___
___
Python-bugs-list mailing list
Unsubscribe: 
http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue9959] int(math.log(4,2)) == 1 instead of 2

2010-09-27 Thread akira

New submission from akira 4kir4...@gmail.com:

$ python3.1 -c'import math; f = math.log(4,2); print(int(f), 
f.as_integer_ratio())'
2 (2, 1)

$ python3.2 -c'import math; f = math.log(4,2); print(int(f), 
f.as_integer_ratio())'
1 (9007199254740991, 4503599627370496)

Python 3.2a2+ (py3k:85028, Sep 27 2010, 16:46:11) 
[GCC 4.4.3] on linux2
Type help, copyright, credits or license for more information.
 import math
 f = math.log(32, 2)
 f
4.999
 int(f)
4
 f.as_integer_ratio()
(5629499534213119, 1125899906842624)

I'm not sure whether it is a bug, but it is an unexpected change in behavior 
between 3.1 and 3.2.

--
components: Library (Lib)
messages: 117444
nosy: akira
priority: normal
severity: normal
status: open
title: int(math.log(4,2)) == 1 instead of 2
type: behavior
versions: Python 3.2

___
Python tracker rep...@bugs.python.org
http://bugs.python.org/issue9959
___
___
Python-bugs-list mailing list
Unsubscribe: 
http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue9959] int(math.log(4,2)) == 1 instead of 2

2010-09-27 Thread Mark Dickinson

Mark Dickinson dicki...@gmail.com added the comment:

No, it's not really a bug:  math.log(x, 2) isn't an atomic operation: it's 
computed internally as something like log(x) / log(2), and since each of the 
three steps (computation of the logs, division) can introduce a small rounding 
error, you shouldn't be surprised if the result doesn't come out exactly.

The difference between 3.1 and 3.2 was a side-effect of a change to remove the 
dependence of the math module on the internal long integer representation.

Having said that, it would be possible to improve the algorithm that's used to 
compute log of an integer (see the loghelper function in Modules/mathmodule.c): 
currently, for positive k, log(2**k) ends up being computed as log(0.5) + 
(k+1)*log(2), which doesn't help;  it would be slightly better if it were 
computed directly as k*log(2) instead.  But you still can't (and shouldn't) 
rely on log(x, 2) giving exact results for powers of 2.

I'm not sure what you're using math.log(x, 2) for, but you may be interested in 
the int.bit_length method.

--
assignee:  - mark.dickinson
nosy: +mark.dickinson

___
Python tracker rep...@bugs.python.org
http://bugs.python.org/issue9959
___
___
Python-bugs-list mailing list
Unsubscribe: 
http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue9959] int(math.log(4,2)) == 1 instead of 2

2010-09-27 Thread akira

akira 4kir4...@gmail.com added the comment:

 No, it's not really a bug: math.log(x, 2) isn't an atomic operation:

It is not a bug, but values of math.log(4) differs between 3.1 and 3.2
i.e., math.log(4.0) in 3.2 returns value that is consistent with
math.log(4) in 3.1 but math.log(4) in 3.2 doesn't.

 I'm not sure what you're using math.log(x, 2) for, but you may be
interested in the int.bit_length method.

The docs for int.bit_length say: 

 if x is nonzero, then x.bit_length() is the unique positive integer
k such that 2**(k-1) = abs(x)  2**k. Equivalently, when abs(x) is
small enough to have a correctly rounded logarithm, then k = 1 +
int(log(abs(x), 2)).

It is expected that int(log(n,2)) produces correct result for small n.

 Having said that, it would be possible to improve the algorithm
 that's used to compute log of an integer (see the loghelper function
 in Modules/mathmodule.c): currently, for positive k, log(2**k) ends
 up being computed as log(0.5) + (k+1)*log(2), which doesn't help; it
 would be slightly better if it were computed directly as k*log(2)
 instead.  But you still can't (and shouldn't) rely on log(x, 2)
 giving exact results for powers of 2.

I've changed loghelper() to return improved result for power of 2

--
keywords: +patch
Added file: http://bugs.python.org/file19030/math_log_power_two.diff

___
Python tracker rep...@bugs.python.org
http://bugs.python.org/issue9959
___
___
Python-bugs-list mailing list
Unsubscribe: 
http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue9959] int(math.log(4,2)) == 1 instead of 2

2010-09-27 Thread akira

Changes by akira 4kir4...@gmail.com:


Added file: http://bugs.python.org/file19031/test_log_power_two.py

___
Python tracker rep...@bugs.python.org
http://bugs.python.org/issue9959
___
___
Python-bugs-list mailing list
Unsubscribe: 
http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue9959] int(math.log(4,2)) == 1 instead of 2

2010-09-27 Thread akira

Changes by akira 4kir4...@gmail.com:


--
type: behavior - feature request

___
Python tracker rep...@bugs.python.org
http://bugs.python.org/issue9959
___
___
Python-bugs-list mailing list
Unsubscribe: 
http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue9959] int(math.log(4,2)) == 1 instead of 2

2010-09-27 Thread Raymond Hettinger

Raymond Hettinger rhettin...@users.sourceforge.net added the comment:

It is not a reasonable request for math float functions to produce exact 
integer values and there is some harm in making further alterations to the 
existing algorithm (the more you tweak it in one place, the more you create 
oddities somewhere else).

There may be a case for a separate math.log2() function but this has never been 
requested before, so it is a low priority.

If the docs for bit_length() bug you, I can change them.  They are meant to be 
the exact math definition of bit_length, not an executable exact result using 
limited precision floating point.   Those docs are trying to inform users about 
bit_length() and are not making a promise about the behavior of math.log().

If you're wanting exact log results for integer inputs and bases, the math 
module is going to disappoint you no matter what we do.  This is a 
limited-precision-floating-point fact of life.

--
nosy: +rhettinger
priority: normal - low

___
Python tracker rep...@bugs.python.org
http://bugs.python.org/issue9959
___
___
Python-bugs-list mailing list
Unsubscribe: 
http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com