
A quick note: I'm working on a special-case compare function for bounded integers for the sort stuff. By looking at the implementation, I figured out that Py_SIZE of a long is the sign times the number of digits (...right?). Before looking at the implementation, though, I had looked for this info in the docs, and I couldn't find it anywhere. Since Py_SIZE is public, I think the documentation should make clear what it returns for PyLongs, for example somewhere on the "Integer Objects" page. Apologies if this is specified somewhere else in the docs and I just couldn't find it. Elliot

On 10/19/2016 09:04 PM, Elliot Gorokhovsky wrote:
I don't think this is right. https://github.com/python/cpython/blob/master/Include/object.h#L119 https://docs.python.org/3/c-api/structures.html#c.Py_SIZE https://docs.python.org/3/c-api/structures.html#c.PyVarObject It returns the `ob_size` fields of a PyVarObject. I think this has to do with objects with variable sizes like lists. PyLongs are not PyVarObjects because they have no notion of length. Why would a long be stored as a sequence of digits instead of a (say) 64 bit integer as 8 bytes? Cheers, Thomas

It's in the code. See longobject.c: Py_SIZE(v) = ndigits*sign; You can also see Py_SIZE(v) used on PyLongs all over the place in longobject.c, for example: v = (PyLongObject *)vv; i = Py_SIZE(v); Just do a ctrl-f for Py_SIZE(v) in longobject.c. Like I said, by looking in the implementation I was able to figure out that Py_SIZE is interpreted as the sign times the number of digits (unless I'm missing something), but this should be in the docs IMO. On Wed, Oct 19, 2016 at 7:24 PM Thomas Nyberg <tomuxiong@gmx.com> wrote:

[Elliot Gorokhovsky <elliot.gorokhovsky@gmail.com>]
Please ignore the other reply you got - they clearly aren't familiar with the code. The details are explained in Include/longintrepr.h. In short, an integer _is_ based on PyVarObject. Py_SIZE is a macro that merely extracts (or allows to set) the ob_size member, the sign of the int is stored as the sign of ob_size (which is really an abuse of ob_size's intended meaning), and the number of "digits" is the absolute value of ob_size. And ob_size is 0 if and only if the int is 0. Note that the number of bits per digit varies across platforms. That too is all explained in longintrepr.h.

On 10/19/2016 09:04 PM, Elliot Gorokhovsky wrote:
I don't think this is right. https://github.com/python/cpython/blob/master/Include/object.h#L119 https://docs.python.org/3/c-api/structures.html#c.Py_SIZE https://docs.python.org/3/c-api/structures.html#c.PyVarObject It returns the `ob_size` fields of a PyVarObject. I think this has to do with objects with variable sizes like lists. PyLongs are not PyVarObjects because they have no notion of length. Why would a long be stored as a sequence of digits instead of a (say) 64 bit integer as 8 bytes? Cheers, Thomas

It's in the code. See longobject.c: Py_SIZE(v) = ndigits*sign; You can also see Py_SIZE(v) used on PyLongs all over the place in longobject.c, for example: v = (PyLongObject *)vv; i = Py_SIZE(v); Just do a ctrl-f for Py_SIZE(v) in longobject.c. Like I said, by looking in the implementation I was able to figure out that Py_SIZE is interpreted as the sign times the number of digits (unless I'm missing something), but this should be in the docs IMO. On Wed, Oct 19, 2016 at 7:24 PM Thomas Nyberg <tomuxiong@gmx.com> wrote:

[Elliot Gorokhovsky <elliot.gorokhovsky@gmail.com>]
Please ignore the other reply you got - they clearly aren't familiar with the code. The details are explained in Include/longintrepr.h. In short, an integer _is_ based on PyVarObject. Py_SIZE is a macro that merely extracts (or allows to set) the ob_size member, the sign of the int is stored as the sign of ob_size (which is really an abuse of ob_size's intended meaning), and the number of "digits" is the absolute value of ob_size. And ob_size is 0 if and only if the int is 0. Note that the number of bits per digit varies across platforms. That too is all explained in longintrepr.h.
participants (3)
-
Elliot Gorokhovsky
-
Thomas Nyberg
-
Tim Peters