Should a // b really be the same as a / b in fields?

98 views
Skip to first unread message

Jeroen Demeyer

unread,
Jan 19, 2016, 6:28:14 AM1/19/16
to sage-devel
Feature or bug?

sage: QQ(7) // QQ(2)
7/2

I would expect

sage: QQ(7) // QQ(2)
3

Vincent Delecroix

unread,
Jan 19, 2016, 6:49:42 AM1/19/16
to sage-...@googlegroups.com
As far as I know we do not have any specifications for //. In euclidean
ring it would be natural for it to be the quotient. But in other situations?

1. Should we always have

a == a//b + a%b

2. Should // always be internal?

Vincent

John Cremona

unread,
Jan 19, 2016, 7:32:13 AM1/19/16
to SAGE devel
On 19 January 2016 at 11:49, Vincent Delecroix
<20100.d...@gmail.com> wrote:
> As far as I know we do not have any specifications for //. In euclidean ring
> it would be natural for it to be the quotient. But in other situations?
>
> 1. Should we always have
>
> a == a//b + a%b
>
> 2. Should // always be internal?
>
> Vincent
>
>
> On 19/01/16 08:28, Jeroen Demeyer wrote:
>>
>> Feature or bug?

I would say "feature" since these are field elements so division is
always exact, unlike ZZ(7)//ZZ(2).

>>
>> sage: QQ(7) // QQ(2)
>> 7/2
>>
>> I would expect
>>
>> sage: QQ(7) // QQ(2)
>> 3

This would only make sense if ZZ was the only ring of which QQ was the
field of fractions. Similarly with rational function fields, in my
opinion.

But I think that

sage: QQ(7) % QQ(2)
1

is definitely a bug, for the same reason! (Should be 0).

John

>>
>
> --
> You received this message because you are subscribed to the Google Groups
> "sage-devel" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to sage-devel+...@googlegroups.com.
> To post to this group, send email to sage-...@googlegroups.com.
> Visit this group at https://groups.google.com/group/sage-devel.
> For more options, visit https://groups.google.com/d/optout.

Vincent Delecroix

unread,
Jan 19, 2016, 7:37:30 AM1/19/16
to sage-...@googlegroups.com
On 19/01/16 09:31, John Cremona wrote:
> On 19 January 2016 at 11:49, Vincent Delecroix
> <20100.d...@gmail.com> wrote:
>> As far as I know we do not have any specifications for //. In euclidean ring
>> it would be natural for it to be the quotient. But in other situations?
>>
>> 1. Should we always have
>>
>> a == a//b + a%b
>>
>> 2. Should // always be internal?
>>
>> On 19/01/16 08:28, Jeroen Demeyer wrote:
>>>
>>> Feature or bug?
>
> I would say "feature" since these are field elements so division is
> always exact, unlike ZZ(7)//ZZ(2).
>
>>>
>>> sage: QQ(7) // QQ(2)
>>> 7/2
>>>
>>> I would expect
>>>
>>> sage: QQ(7) // QQ(2)
>>> 3
>
> This would only make sense if ZZ was the only ring of which QQ was the
> field of fractions. Similarly with rational function fields, in my
> opinion.
>
> But I think that
>
> sage: QQ(7) % QQ(2)
> 1
>
> is definitely a bug, for the same reason! (Should be 0).

That contradicts the proposal at

https://groups.google.com/forum/#!topic/sage-devel/PfMop0nyiL0

John Cremona

unread,
Jan 19, 2016, 8:18:58 AM1/19/16
to SAGE devel
On 19 January 2016 at 12:37, Vincent Delecroix
You are right, it does. The trouble is that there seem to be two ways
to generalize % from ZZ to QQ or RR: I was thinking of it as the
quotient, or approximate quotient for ZZ; but the other thread sees
x%y as the integer part of x/y.

I agree that it might be useful to have a computation with (say) 100 % pi:

sage: 100.0 % RR(pi)
-0.530964914873380

(without the RR one gets as error since % is not defined for SR,SR
arguments), and it would be pretty stupid to give 0 just because a
pure mathematician says that RR is a field so the division is exact.

So provided that the documentation is very clear, defining x%y as the
integer paert of x/y, for any subset of RR, makes sense.

(What about CC?)

Johan S. R. Nielsen

unread,
Jan 19, 2016, 8:57:28 AM1/19/16
to sage-...@googlegroups.com
The behaviour for ZZ--QQ--RR decided in that other thread are taking
quotients over the sub-ring ZZ. More specifically:

if a,b are in ZZ, QQ or RR then it was decided that a % b should
implicitly satisfy:

a == (a//b) * b + a%b

and a//b in ZZ and a%b has norm smaller than b (norm as in euclidean
domain, and some fix to disallow a%b < 0). If we decided instead that
when a,b in QQ then the a//b should be taken in Q, that would imply a//b
= a/b and a%b = 0. The difference is really which ring a//b should be
required to land in.

More generally, if we have a ring R and a subring S, we could introduce
a function //_S and %_S such that for a,b in R then

a == (a //_S b) * b + a %_S b

where (a //_S b) in S and (a %_S b) has norm < |b|. I'm not sure what
the requirements of R and S should be for such functions to exist.
Apart from all the examples with ZZ, QQ and RR, it seems to work for
e.g. R = K(x) and S = K[x] for a field K with |f1/f2| being deg f1 - deg
f2.

It might seem mathematically "arbitrary" to say that // defaults to
//_ZZ according to the above notation, whenever a,b in RR, if the above
holds for a wide variety of R and S.

Best,
Johan

>>>> 1. Should we always have
>>>>
>>>> a == a//b + a%b

--

Jeroen Demeyer

unread,
Jan 19, 2016, 4:03:43 PM1/19/16
to sage-...@googlegroups.com
On 2016-01-19 12:49, Vincent Delecroix wrote:
> 1. Should we always have
>
> a == a//b + a%b

I guess you mean

a == (a//b)*b + a%b

Buy yes, this invariant is very important and should always be satisfied.

Jeroen Demeyer

unread,
Jan 19, 2016, 4:09:28 PM1/19/16
to sage-...@googlegroups.com
On 2016-01-19 13:31, John Cremona wrote:
> This would only make sense if ZZ was the only ring of which QQ was the
> field of fractions. Similarly with rational function fields, in my
> opinion.

Well, you are thinking too mathematical. Of course, defining a//b = a/b
makes any field into a Euclidean domain. However, this isn't very
useful. If the user really wanted to just divide rational numbers, then
he could just write a/b instead of a//b.

Defining // on QQ as extending // from ZZ is a lot more useful and
intuitive, even though it's not canonical from a mathematical point of view.

Jeroen.

Volker Braun

unread,
Jan 19, 2016, 4:50:25 PM1/19/16
to sage-devel
Presumably nobody has a problem with 

sage: R.<x> = QQ[]
sage: (3*x^2+1) // (2*x)
3/2*x

and it would be rather strange if the binary operations on the scalars behave different in QQ vs degree-0-part(QQ[x]). Whereas it shouldn't come as too much of a surprise that division-related operations behave differently in ZZ and QQ.  

Jeroen Demeyer

unread,
Jan 20, 2016, 3:28:23 AM1/20/16
to sage-...@googlegroups.com
On 2016-01-19 22:50, Volker Braun wrote:
> Presumably nobody has a problem with
>
> sage: R.<x> = QQ[]
> sage: (3*x^2+1) // (2*x)
> 3/2*x
>
> and it would be rather strange if the binary operations on the scalars
> behave different in QQ vs degree-0-part(QQ[x]).

Well, you cannot have a fully consistent floor division in any case:
Either you make floor division on QQ consistent with ZZ or with QQ[x]
but you cannot have both. Personally, I would prefer making it
consistent with ZZ.

If E is any Euclidean domain, then you can extend // naturally to the
fraction field of E. I think this is the most useful definition. This
would also be consistent with gcd() where we already treat QQ and QQ[x]
differently:

sage: R.<x> = QQ[]
sage: gcd(QQ(2), QQ(2))
2
sage: gcd(R(2), R(2))
1

Of course we could just always answer "1" in both cases which would be
mathematically correct but rather useless.


Jeroen.

Volker Braun

unread,
Jan 20, 2016, 5:17:33 AM1/20/16
to sage-devel
On Wednesday, January 20, 2016 at 8:28:23 AM UTC, Jeroen Demeyer wrote:
Well, you cannot have a fully consistent floor division in any case:
Either you make floor division on QQ consistent with ZZ or with QQ[x]
but you cannot have both. Personally, I would prefer making it
consistent with ZZ.

As I said in the previous email (the piece that you graciously left out), this isn't really consistent with the division operation on ZZ. Really division is fundamentally different in QQ so floor division ought to be different, too. 

In any case there is a way to be confused about this, so we should more think about a warning and/or disabling floor division on QQ.

Jeroen Demeyer

unread,
Jan 20, 2016, 5:22:55 AM1/20/16
to sage-...@googlegroups.com
On 2016-01-20 11:17, Volker Braun wrote:
> On Wednesday, January 20, 2016 at 8:28:23 AM UTC, Jeroen Demeyer wrote:
>
> Well, you cannot have a fully consistent floor division in any case:
> Either you make floor division on QQ consistent with ZZ or with QQ[x]
> but you cannot have both. Personally, I would prefer making it
> consistent with ZZ.
>
>
> As I said in the previous email (the piece that you graciously left
> out), this isn't really consistent with the division operation on ZZ.

In QQ, I would define a//b = floor(a/b).

Why do you consider this not "really consistent with the division
operation on ZZ."? Neither your previous post nor this one explains that.

Volker Braun

unread,
Jan 20, 2016, 6:32:43 AM1/20/16
to sage-devel
On Wednesday, January 20, 2016 at 10:22:55 AM UTC, Jeroen Demeyer wrote:
In QQ, I would define a//b = floor(a/b).
Why do you consider this not "really consistent with the division
operation on ZZ."? Neither your previous post nor this one explains that.

That definition doesn't work for ZZ where you can't necessarily divide. Of course you can define as ZZ-floor division as the above operation in QQ, but thats doesn't generalize to other rings. And, as you know, one can define floor division just in the ring without referring to the fraction field.

Jeroen Demeyer

unread,
Jan 20, 2016, 7:28:48 AM1/20/16
to sage-...@googlegroups.com
On 2016-01-20 12:32, Volker Braun wrote:
> Of course you can define as ZZ-floor division as the above operation in
> QQ, but thats doesn't generalize to other rings.

True, this doesn't work in full mathematical generality. But that's not
a good reason to just throw everything away.

Many useful Euclidean divisions can be defined in terms of a
"floor"-like function on the fraction field.

More precisely, we could define a *floor domain* as a domain R together
with a function floor: frac(R)->R such that the operation a//b, defined
as floor(a/b) makes R into a Euclidean domain.

Then ZZ is a floor domain and K[x] is also a floor-domain. Also the
Euclidean quadratic imaginary rings like Z[I] are floor domains.


Jeroen.

William Stein

unread,
Jan 20, 2016, 7:37:42 AM1/20/16
to sage-devel
When lurking and reading this thread, I keep being reminded of Justin
Walker's remarks that a "principle of least surprise" can be useful in
such design decisions. In this particular case, there's two things
that argue for what Jeroen suggests:

- If you have integers a and b, and write a//b then it's very clear
what happens. If somehow you make a or b into a rational number, then
do a//b, it would be really confusing if you get a completely
different answer. A similar issue has tripped people up with GCD,
LCM, etc., in the past.

- // is literally called "floordiv" or "floor division" in Python.
The closest way of writing this is math.floor(a/b).

- Python already decided what floordiv means for Python floats. It
would be natural if for Sage rationals a,b, we have float(a//b) "="
float(a)//float(b).

So I think either we implement what Jeroen suggests, or raise an exception.

-- William
> --
> You received this message because you are subscribed to the Google Groups
> "sage-devel" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to sage-devel+...@googlegroups.com.
> To post to this group, send email to sage-...@googlegroups.com.
> Visit this group at https://groups.google.com/group/sage-devel.
> For more options, visit https://groups.google.com/d/optout.



--
William (http://wstein.org)

Volker Braun

unread,
Jan 20, 2016, 9:38:05 AM1/20/16
to sage-devel
Python 2.x also decided that integer division is C division, which we totally violate. So we have never kept with the Python semantics for division. Not that Python has rationals out of the box anyways. Whatever implementation we chose, people will trip over that. The only thing more confusing than having two different but completely reasonable behaviors is switching between them.

PS: yes I know the py3 changes...

William Stein

unread,
Jan 20, 2016, 9:49:56 AM1/20/16
to sage-devel
On Wed, Jan 20, 2016 at 6:38 AM, Volker Braun <vbrau...@gmail.com> wrote:
> So we have never kept with the Python semantics for
> division. Not that Python has rationals out of the box anyways. Whatever
> implementation we chose, people will trip over that.
> The only thing more
> confusing than having two different but completely reasonable behaviors is
> switching between them.

I should add that the stupid reason things work this way now:

sage: QQ(7) // QQ(2)
7/2

are because of this commit by me in 2007, in which I just tossed in a
one-linear for all fields in Sage that does the above.:

https://github.com/sagemath/sage/commit/bb691454e4717beb97dc3225bd7d291bc14e3250

Volker, you're definitely right that changing this behavior has the
potential to cause a lot of confusion and potential bugs in code.
Oh the pain.

Making __floordiv__ throw an exception for all fields, instead of
silently doing normal div, seems like the only safe thing to do. I
wish that's what I had done (or left things as) back in 2007.

All that said, without history in the way, making floordiv agree with
float floor div would be nice.

Sorry for that patch.

-- William

--
William (http://wstein.org)

Jeroen Demeyer

unread,
Jan 20, 2016, 9:53:31 AM1/20/16
to sage-...@googlegroups.com
On 2016-01-20 15:49, William Stein wrote:
> All that said, without history in the way, making floordiv agree with
> float floor div would be nice.

For the record, this is #15260.
Reply all
Reply to author
Forward
0 new messages