Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
cpython
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
cpython
Commits
54bc1ec4
Commit
54bc1ec4
authored
Dec 17, 2008
by
Mark Dickinson
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Forward merge of r67822 to py3k: add bit_length method to int.
parent
81c93fb4
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
188 additions
and
1 deletion
+188
-1
Doc/library/stdtypes.rst
Doc/library/stdtypes.rst
+39
-0
Doc/whatsnew/2.7.rst
Doc/whatsnew/2.7.rst
+17
-1
Doc/whatsnew/3.1.rst
Doc/whatsnew/3.1.rst
+22
-0
Lib/test/test_long.py
Lib/test/test_long.py
+36
-0
Misc/ACKS
Misc/ACKS
+1
-0
Misc/NEWS
Misc/NEWS
+2
-0
Objects/longobject.c
Objects/longobject.c
+71
-0
No files found.
Doc/library/stdtypes.rst
View file @
54bc1ec4
...
...
@@ -419,6 +419,40 @@ Notes:
overflow check.
Additional Methods on Integer Types
-----------------------------------
.. method:: int.bit_length()
For any integer ``x``, ``x.bit_length()`` returns the number of
bits necessary to represent ``x`` in binary, excluding the sign
and any leading zeros::
>>> n = 37
>>> bin(n)
'0b100101'
>>> n.bit_length()
6
>>> n = -0b00011010
>>> n.bit_length()
5
More precisely, if ``x`` is nonzero then ``x.bit_length()`` is the
unique positive integer ``k`` such that ``2**(k-1) <= abs(x) <
2**k``. Equivalently, ``x.bit_length()`` is equal to ``1 +
floor(log(x, 2))`` [#]_ . If ``x`` is zero then ``x.bit_length()``
gives ``0``.
Equivalent to::
def bit_length(self):
'Number of bits necessary to represent self in binary.'
return len(bin(self).lstrip('-0b'))
.. versionadded:: 3.1
Additional Methods on Float
---------------------------
...
...
@@ -2639,6 +2673,11 @@ types, where they are relevant. Some of these are not reported by the
.. [#] As a consequence, the list ``[1, 2]`` is considered equal to ``[1.0, 2.0]``, and
similarly for tuples.
.. [#] Beware of this formula! It's mathematically valid, but as a
Python expression it will not give correct results for all ``x``,
as a consequence of the limited precision of floating-point
arithmetic.
.. [#] They must have since the parser can't tell the type of the operands.
.. [#] To format only a tuple you should therefore provide a singleton tuple whose only
...
...
Doc/whatsnew/2.7.rst
View file @
54bc1ec4
...
...
@@ -66,7 +66,23 @@ Other Language Changes
Some smaller changes made to the core Python language are:
* List of changes to be written here.
* The :func:`int` and :func:`long` types gained a ``bit_length``
method that returns the number of bits necessary to represent
its argument in binary::
>>> n = 37
>>> bin(37)
'0b100101'
>>> n.bit_length()
6
>>> n = 2**123-1
>>> n.bit_length()
123
>>> (n+1).bit_length()
124
(Contributed by Fredrik Johansson and Victor Stinner; :issue:`3439`.)
.. ======================================================================
...
...
Doc/whatsnew/3.1.rst
View file @
54bc1ec4
...
...
@@ -66,4 +66,26 @@ This article explains the new features in Python 3.1, compared to 3.0.
.. ======================================================================
Other Language Changes
======================
Some smaller changes made to the core Python language are:
* The :func:`int` type gained a ``bit_length`` method that returns the
number of bits necessary to represent its argument in binary::
>>> n = 37
>>> bin(37)
'0b100101'
>>> n.bit_length()
6
>>> n = 2**123-1
>>> n.bit_length()
123
>>> (n+1).bit_length()
124
(Contributed by Fredrik Johansson and Victor Stinner; :issue:`3439`.)
.. ======================================================================
Lib/test/test_long.py
View file @
54bc1ec4
...
...
@@ -3,6 +3,7 @@ from test import support
import
sys
import
random
import
math
# Used for lazy formatting of failure messages
class
Frm
(
object
):
...
...
@@ -836,6 +837,41 @@ class LongTest(unittest.TestCase):
self
.
assertTrue
(
i
-
i
is
0
)
self
.
assertTrue
(
0
*
i
is
0
)
def
test_bit_length
(
self
):
tiny
=
1e-10
for
x
in
range
(
-
65000
,
65000
):
k
=
x
.
bit_length
()
# Check equivalence with Python version
self
.
assertEqual
(
k
,
len
(
bin
(
x
).
lstrip
(
'-0b'
)))
# Behaviour as specified in the docs
if
x
!=
0
:
self
.
assert_
(
2
**
(
k
-
1
)
<=
abs
(
x
)
<
2
**
k
)
else
:
self
.
assertEqual
(
k
,
0
)
# Alternative definition: x.bit_length() == 1 + floor(log_2(x))
if
x
!=
0
:
# When x is an exact power of 2, numeric errors can
# cause floor(log(x)/log(2)) to be one too small; for
# small x this can be fixed by adding a small quantity
# to the quotient before taking the floor.
self
.
assertEqual
(
k
,
1
+
math
.
floor
(
math
.
log
(
abs
(
x
))
/
math
.
log
(
2
)
+
tiny
))
self
.
assertEqual
((
0
).
bit_length
(),
0
)
self
.
assertEqual
((
1
).
bit_length
(),
1
)
self
.
assertEqual
((
-
1
).
bit_length
(),
1
)
self
.
assertEqual
((
2
).
bit_length
(),
2
)
self
.
assertEqual
((
-
2
).
bit_length
(),
2
)
for
i
in
[
2
,
3
,
15
,
16
,
17
,
31
,
32
,
33
,
63
,
64
,
234
]:
a
=
2
**
i
self
.
assertEqual
((
a
-
1
).
bit_length
(),
i
)
self
.
assertEqual
((
1
-
a
).
bit_length
(),
i
)
self
.
assertEqual
((
a
).
bit_length
(),
i
+
1
)
self
.
assertEqual
((
-
a
).
bit_length
(),
i
+
1
)
self
.
assertEqual
((
a
+
1
).
bit_length
(),
i
+
1
)
self
.
assertEqual
((
-
a
-
1
).
bit_length
(),
i
+
1
)
def
test_main
():
support
.
run_unittest
(
LongTest
)
...
...
Misc/ACKS
View file @
54bc1ec4
...
...
@@ -344,6 +344,7 @@ Drew Jenkins
Flemming Kjr Jensen
Jiba
Orjan Johansen
Fredrik Johansson
Gregory K. Johnson
Simon Johnston
Evan Jones
...
...
Misc/NEWS
View file @
54bc1ec4
...
...
@@ -12,6 +12,8 @@ What's New in Python 3.1 alpha 0
Core and Builtins
-----------------
- Issue #3439: Add a bit_length method to int.
- Issue #2173: When getting device encoding, check that return value of
nl_langinfo is not the empty string. This was causing silent build
failures on OS X.
...
...
Objects/longobject.c
View file @
54bc1ec4
...
...
@@ -3650,6 +3650,75 @@ long_sizeof(PyLongObject *v)
return
PyLong_FromSsize_t
(
res
);
}
static
const
unsigned
char
BitLengthTable
[
32
]
=
{
0
,
1
,
2
,
2
,
3
,
3
,
3
,
3
,
4
,
4
,
4
,
4
,
4
,
4
,
4
,
4
,
5
,
5
,
5
,
5
,
5
,
5
,
5
,
5
,
5
,
5
,
5
,
5
,
5
,
5
,
5
,
5
};
static
PyObject
*
long_bit_length
(
PyLongObject
*
v
)
{
PyLongObject
*
result
,
*
x
,
*
y
;
Py_ssize_t
ndigits
,
msd_bits
=
0
;
digit
msd
;
assert
(
v
!=
NULL
);
assert
(
PyLong_Check
(
v
));
ndigits
=
ABS
(
Py_SIZE
(
v
));
if
(
ndigits
==
0
)
return
PyLong_FromLong
(
0
);
msd
=
v
->
ob_digit
[
ndigits
-
1
];
while
(
msd
>=
32
)
{
msd_bits
+=
6
;
msd
>>=
6
;
}
msd_bits
+=
(
long
)(
BitLengthTable
[
msd
]);
if
(
ndigits
<=
PY_SSIZE_T_MAX
/
PyLong_SHIFT
)
return
PyLong_FromSsize_t
((
ndigits
-
1
)
*
PyLong_SHIFT
+
msd_bits
);
/* expression above may overflow; use Python integers instead */
result
=
(
PyLongObject
*
)
PyLong_FromSsize_t
(
ndigits
-
1
);
if
(
result
==
NULL
)
return
NULL
;
x
=
(
PyLongObject
*
)
PyLong_FromLong
(
PyLong_SHIFT
);
if
(
x
==
NULL
)
goto
error
;
y
=
(
PyLongObject
*
)
long_mul
(
result
,
x
);
Py_DECREF
(
x
);
if
(
y
==
NULL
)
goto
error
;
Py_DECREF
(
result
);
result
=
y
;
x
=
(
PyLongObject
*
)
PyLong_FromLong
(
msd_bits
);
if
(
x
==
NULL
)
goto
error
;
y
=
(
PyLongObject
*
)
long_add
(
result
,
x
);
Py_DECREF
(
x
);
if
(
y
==
NULL
)
goto
error
;
Py_DECREF
(
result
);
result
=
y
;
return
(
PyObject
*
)
result
;
error:
Py_DECREF
(
result
);
return
NULL
;
}
PyDoc_STRVAR
(
long_bit_length_doc
,
"int.bit_length() -> int
\n
\
\n
\
Number of bits necessary to represent self in binary.
\n
\
>>> bin(37)
\n
\
'0b100101'
\n
\
>>> (37).bit_length()
\n
\
6"
);
#if 0
static PyObject *
long_is_finite(PyObject *v)
...
...
@@ -3661,6 +3730,8 @@ long_is_finite(PyObject *v)
static
PyMethodDef
long_methods
[]
=
{
{
"conjugate"
,
(
PyCFunction
)
long_long
,
METH_NOARGS
,
"Returns self, the complex conjugate of any int."
},
{
"bit_length"
,
(
PyCFunction
)
long_bit_length
,
METH_NOARGS
,
long_bit_length_doc
},
#if 0
{"is_finite", (PyCFunction)long_is_finite, METH_NOARGS,
"Returns always True."},
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment