Shouldn't by by mathematical definition -x // y be the same as -(x // y)? But when assign x=2, y=3 you get:
-2 // 3 -1 -(2 // 3) 0
And also:
2 // -3 -1 -2 // -3 0
And even more:
int(-2 / 3) 0 int(2 / -3) 0
I think this rather odd. Is there any deeper reason to this behaviour? I guess changing this will break a lot of code, but why does it behave like this?
-panzi
Mathias Panzenböck wrote:
Shouldn't by by mathematical definition -x // y be the same as -(x // y)? But when assign x=2, y=3 you get:
-2 // 3 -1 -(2 // 3) 0
And also:
2 // -3 -1 -2 // -3 0
And even more:
int(-2 / 3) 0 int(2 / -3) 0
I think this rather odd. Is there any deeper reason to this behaviour? I guess changing this will break a lot of code, but why does it behave like this?
It's so that:
y == (y // x) * x + (y % x)
is always True (assuming x != 0).
On 5/6/2010 9:09 PM, MRAB wrote:
Mathias Panzenböck wrote:
Shouldn't by by mathematical definition -x // y be the same as -(x // y)?
When defining division of counts, which have no signs, quotient and remainder cannot be negative. So division both rounds down and rounds toward zero. It both truncates and floors.
When defining division on integers (signed counts), one can either define it to round down or to round toward zero, but obviously not both. As mentioned in the article Chris linked to, http://en.wikipedia.org/wiki/Modulo_operation one can also round down or up depending on the sign of the divisor.
The above definition is 'round toward zero' truncation. It has the anomaly that 0 then is the rounded value (and representative) of all ratios in the doubly open length-2 range (-1, 1) while all other quotients represent a half-open length-1 range. The is because -0 == 0 whereas -n != n for all other ints. For 'round down', every quotient, including 0, represents a half-open length-1 range.
It's so that: y == (y // x) * x + (y % x) is always True (assuming x != 0).
No, this is true for any definition of y//x if you define y % x to be y - (y//x)*x. But for truncation, this mean that the sign of y%x depends on the sign of y rather than the sign of x, as with floor division. The latter is probably more useful more of the time. For instance, y % 2 has only 2 possible values (0,1) with flooring rather than three (-1, 0, 1) as with truncation.
Terry Jan Reedy
On Thu, May 6, 2010 at 5:43 PM, Mathias Panzenböck
grosser.meister.morti@gmx.net wrote:
Shouldn't by mathematical definition -x // y be the same as -(x // y)?
Not necessarily, that's only one possible definition; it is the one that happens to be used in number theory, but it's not the only possible one. Most programming languages don't choose that definition and instead choose one of 2 other definitions that use the signs of the operands to determine what signs a%b and a//b will have (the difference between the 2 definitions being which operand's sign is used). See http://en.wikipedia.org/wiki/Modulo_operation for a thorough explanation.
I think this rather odd. Is there any deeper reason to this behaviour? I guess changing this will break a lot of code, but why does it behave like this?
I would suppose it's what programmers have found more useful/intuitive. Most programmers aren't number theorists.
Cheers,
On Fri, 07 May 2010 02:43:42 +0200 Mathias Panzenböck grosser.meister.morti@gmx.net wrote:
-2 // 3
-1
??? This is simply wrong, for me. The algorithm seems to use floor instead of integral part! But I'm unsure about math definition.
Denis
vit esse estrany ☣
spir.wikidot.com
On Thu, May 6, 2010 at 17:43, Mathias Panzenböck grosser.meister.morti@gmx.net wrote:
Shouldn't by by mathematical definition -x // y be the same as -(x // y)? But when assign x=2, y=3 you get:
-2 // 3 -1 -(2 // 3) 0
And also:
2 // -3 -1 -2 // -3 0
And even more:
int(-2 / 3) 0 int(2 / -3) 0
I think this rather odd. Is there any deeper reason to this behaviour? I guess changing this will break a lot of code, but why does it behave like this?
Operator precedence; unary negation (the 'factor' rule from Grammar/Grammar)
binds more tightly than // (the 'term' rule), thus applying the negation to
'2' before applying the '//'. Making it bind as -(x // y)
would require
introducing a special grammar rule just to make sure that unary negation on
binary operators like this worked this way. And I am not even sure if that
would be unambiguous in Python's LL(1) grammar.
-Brett
>
-panzi
Python-ideas mailing list Python-ideas@python.org http://mail.python.org/mailman/listinfo/python-ideas