your opinions about 0.digits()

3 views
Skip to first unread message

vgermrk

unread,
Apr 3, 2008, 8:51:26 AM4/3/08
to sage-devel
Hi! I want to hear your opinions about a little problem.

The following bug is already reported as #2232:
"1.digits(16,'0123456789abcdef')" returns "['1']"
but "0.digits(16,'0123456789abcdef')" returns "[]" (and not "['0']"
as i wish)

So i started looking at the code to fix this little problem.
But it looks like this was (maybe) intended, because the docstring
says something like "0 has 0 digits", and so in particular
"0.digits(base=10)" returns "[]".

And here is my question:
Should "0.digits(base=10)" return "[]" or "[0]" (which i prefer, but
i'm here to get your opinions)

Clearly i can just fix my first problem
("0.digits(16,'0123456789abcdef')") and let "0.digits(base=10)" as it
is, but i think this is inconsistent or inconsequent.

-vgermrk-

Joel B. Mohler

unread,
Apr 3, 2008, 10:05:29 AM4/3/08
to sage-...@googlegroups.com
On Thursday 03 April 2008 08:51, vgermrk wrote:
> Hi! I want to hear your opinions about a little problem.
>
> The following bug is already reported as #2232:
> "1.digits(16,'0123456789abcdef')" returns "['1']"
> but "0.digits(16,'0123456789abcdef')" returns "[]" (and not "['0']"
> as i wish)

Since I was the last person to touch the digits method, I'll state my case.
Note that digits was (I think) inconsistent in this regard before my
modifications -- I believe binary was different than other bases, but I don't
recall which way.

I intentionally made 0.digits() return [] because that seems to me the most
consistent mathematical thing to do. To make 0.digits() return [0] seems
inconsistent to me because we don't pad any other number with 0's to the
left. I'm sure that one could imagine use cases where you would really want
either implementation for 0.digits().

Here's a feature I would like that you might like as well:
sage: #hypothetical code ahead
sage: 1.digits(padto=3)
[1, 0, 0]
sage: 0.digits(padto=1)
[0]
sage: 123456.digits(padto=5) # padto is only a minimum
[6, 5, 4, 3, 2, 1]
In short, the 'padto' parameter would state the minimal length of the returned
list and we would put sufficient zeros to make the list that length. This
would enable things like this (I suspect there's better ways to do this, but
this is what I always think of when I want listings of power-set-like
things):
sage: for i in srange(8): i.digits(base=2,padto=3)
[0, 0, 0]
[1, 0, 0]
[0, 1, 0]
[1, 1, 0]
[0, 0, 1]
[1, 0, 1]
[0, 1, 1]
[1, 1, 1]

So, the current returns are what occurs with padto=0.

--
Joel

David Harvey

unread,
Apr 3, 2008, 10:10:38 AM4/3/08
to sage-...@googlegroups.com

On Apr 3, 2008, at 10:05 AM, Joel B. Mohler wrote:

> I intentionally made 0.digits() return [] because that seems to me
> the most
> consistent mathematical thing to do.

+1

david

Alex Ghitza

unread,
Apr 3, 2008, 10:37:46 AM4/3/08
to sage-...@googlegroups.com
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Joel B. Mohler wrote:
|
| Since I was the last person to touch the digits method, I'll state my
case.
| Note that digits was (I think) inconsistent in this regard before my
| modifications -- I believe binary was different than other bases, but
I don't
| recall which way.
|
| I intentionally made 0.digits() return [] because that seems to me the
most
| consistent mathematical thing to do. To make 0.digits() return [0] seems
| inconsistent to me because we don't pad any other number with 0's to the
| left. I'm sure that one could imagine use cases where you would
really want
| either implementation for 0.digits().
|

I guess this is a question of convention, and depends on how you think
of "digit":

(1) a digit is a symbol used to construct representations of numbers,
and so the base 10 digits are: "0", "1", ..., "9". In this case,
0.ndigits() should return 1 and 0.digits() should return [0]

(2) when writing an integer n in base b, you compute a b-adic expansion
n = d_0 + d_1*b^1 + d_2*b^2 + ... + d_k b^k
with d_k nonzero; you call the d_i the "digits" of a. Then 0 *has no
such expansion*, therefore 0.digits() should return [] and 0.ndigits()
should return 0.


I used to be very much in favor of option (1), but now that I actually
thought about it for 30 seconds, it doesn't really matter to me as long
as we document the chosen convention properly, and we are consistent.
Note that at the moment 0.digits() does (2) and 0.ndigits() does (1),
which is really bad.

Alex

- --
Alexandru Ghitza
Assistant Professor
Department of Mathematics
Colby College
Waterville, ME 04901
http://bayes.colby.edu/~ghitza/
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.7 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iD8DBQFH9Ou6dZTaNFFPILgRAlgJAJ4hBj/GR1NdxgkXxIXEtoeT12ry4gCgjgYq
3DDU6zKocIuQTlNHoiCL3s0=
=g8+f
-----END PGP SIGNATURE-----

Joel B. Mohler

unread,
Apr 3, 2008, 11:00:01 AM4/3/08
to sage-...@googlegroups.com
On Thursday 03 April 2008 10:37, Alex Ghitza wrote:
> Note that at the moment 0.digits() does (2) and 0.ndigits() does (1),
> which is really bad.

Yes, this is very bad. I was not aware of the ndigits convention until after
the digits patch I wrote was included. On this topic, we also need a vote
about digits/ndigits disagreement about the defaulted base. One defaults to
base 2 and the other to base 10.

I vote that they both default to base 10.

Somewhat related: The 'bits' and 'ndigits(base=2)' are redundant. This
violates the python mantra (but, I personally am not entirely fond of the
one-way-to-do-things mantra). I think that 'bits' should be 'nbits'.

Sorry, this is a bit of thread-jacking.

I'd be happy to write a patch tweaking a few of these things if there were
consensus about the tweaking.

--
Joel

Carl Witty

unread,
Apr 3, 2008, 1:13:15 PM4/3/08
to sage-devel
On Apr 3, 7:37 am, Alex Ghitza <aghi...@gmail.com> wrote:
> I guess this is a question of convention, and depends on how you think
> of "digit":
>
> (1) a digit is a symbol used to construct representations of numbers,
> and so the base 10 digits are: "0", "1", ..., "9". In this case,
> 0.ndigits() should return 1 and 0.digits() should return [0]
>
> (2) when writing an integer n in base b, you compute a b-adic expansion
> n = d_0 + d_1*b^1 + d_2*b^2 + ... + d_k b^k
> with d_k nonzero; you call the d_i the "digits" of a. Then 0 *has no
> such expansion*, therefore 0.digits() should return [] and 0.ndigits()
> should return 0.

I have a slight preference for (2), but I would be happy either way as
long as everything is consistent and documented.

Carl

John Cremona

unread,
Apr 3, 2008, 3:14:47 PM4/3/08
to sage-...@googlegroups.com
We have to regard 0 as a special case, I don't think there's any point
in pretending otherwise. If all leading zeros were stripped off in
all cases then the string representing 0 would be the empty string,
and obviously that would be silly.

I went to see what the degree of the 0 polynomial is in Sage,
expecting one of : -Infinity, Undefined, and found it is -1. Well ok,
that is one convention, but please do not try to convince me that it
is anything other than a convention. (I prefer -Infinity but am not
fussy).

John

Joel B. Mohler

unread,
Apr 3, 2008, 3:34:40 PM4/3/08
to sage-...@googlegroups.com
On Thursday 03 April 2008 15:14, John Cremona wrote:
> We have to regard 0 as a special case, I don't think there's any point
> in pretending otherwise.  If all leading zeros were stripped off in
> all cases then the string representing 0 would be the empty string,
> and obviously that would be silly.

Certainly, 0 is a special case (and the example of string is crystal clear).
However, the question is which way more users of 'digits' want the results.
Not having a list of uses (and future uses!) of 'digits' on hand at the
moment, it's a bit of a shot in the dark which special casing might be
preferred. I think that the most likely correct answer for general cases is
the empty list (after all, we'd like to not pass on the special case to the
end-user more than we have to.)

--
Joel

John Cremona

unread,
Apr 3, 2008, 3:48:47 PM4/3/08
to sage-...@googlegroups.com
That seem reasonable to me. If users expected the number of digits to
always equal the length of the string representation, then what about
negative integers?

Of course we could restrict the ndigits() function to positive integers only...

John

William Stein

unread,
Apr 3, 2008, 3:56:05 PM4/3/08
to sage-...@googlegroups.com
On Thu, Apr 3, 2008 at 12:14 PM, John Cremona <john.c...@gmail.com> wrote:
>
> We have to regard 0 as a special case, I don't think there's any point
> in pretending otherwise. If all leading zeros were stripped off in
> all cases then the string representing 0 would be the empty string,
> and obviously that would be silly.
>
> I went to see what the degree of the 0 polynomial is in Sage,
> expecting one of : -Infinity, Undefined, and found it is -1. Well ok,
> that is one convention, but please do not try to convince me that it
> is anything other than a convention.

I'll try anyways to at least convince you that there was a
good reason at the time when I chose that convention.
I defined degree that way specifically for consistency
with Magma:

> R<x> := PolynomialRing(RationalField());
> Degree(R!0);
-1

I implemented the first version of polynomials in Sage in the very
early days of Sage, and for quite a long time consistency with
Magma was a guiding design constraint for Sage (i.e., if a lot
more people hadn't got involved, Sage/Magma could very well
have been somewhat like Octave/Matlab).

Also, Sage didn't have any notion of infinity when I first
implemented polynomials...

--William

John Cremona

unread,
Apr 3, 2008, 4:08:08 PM4/3/08
to sage-...@googlegroups.com
Fine -- clearly a sensible choice at the time, and I would not dream
of changing that now!

John

vgermrk

unread,
Apr 4, 2008, 4:56:08 AM4/4/08
to sage-devel
I wrote a patch, which fixes the issue (#2232) and adds a padto-
parameter (as suggested).

Feel free to review :-)
http://trac.sagemath.org/sage_trac/ticket/2232

-vgermrk-
Reply all
Reply to author
Forward
0 new messages