Second, in Turbo C -111%10=-1 however in python -111%10=9. Is one or
the other in error? Is this a known gotcha? I tried to google the
subject however one cannot google the symbol %. Thanks in advance.
Dotan Cohen
http://what-is-what.com
http://gibberish.co.il
--
א-ב-ג-ד-ה-ו-ז-ח-ט
י-ך-כ-ל-ם-מ-ן-נ-ס
ע-ף-פ-ץ-צ-ק-ר-ש-ת
A: Because it messes up the order in which people normally read text.
Q: Why is top-posting such a bad thing?
> FIrst of all, how is the % symbol (as in 70%6=4) called in English?
It's called "modulo", but most people pronounce it "mod".
It's documented at http://docs.python.org/ref/binary.html
The % operator is called "modulo" in English. I don't think the
difference in implementation is an error. It's just a difference of
calculation method.
Python will always yield a number x = m%n such that 0 <= x < n, but
Turbo C will always yield a number such that if x = m%n -x = -m%n. That
is, since 111 % 10 = 1, -111 % 10 = -1. The two values will always
differ by n (as used above).
I'm sure there are mathematicians on the list who can give you a more
technical, precise explanation of the reasons for the different results.
Cheers,
Cliff
I don't know if there's a mathematical explanation of the difference,
but I prefer the behaviour of the Python modulo operator because for
any a, b, n, if a = b (mod n) holds then the Python expression 'a % n
== b % n' evaluates to True.
--
Arnaud
> Dotan Cohen wrote:
>> FIrst of all, how is the % symbol (as in 70%6=4) called in English?
>>
>> Second, in Turbo C -111%10=-1 however in python -111%10=9. Is one or
>> the other in error? Is this a known gotcha? I tried to google the
>> subject however one cannot google the symbol %. Thanks in advance.
>>
>> Dotan Cohen
>>
>
> The % operator is called "modulo" in English. I don't think the
> difference in implementation is an error. It's just a difference of
> calculation method.
>
> Python will always yield a number x = m%n such that 0 <= x < n, but
> Turbo C will always yield a number such that if x = m%n -x = -m%n. That
> is, since 111 % 10 = 1, -111 % 10 = -1. The two values will always
> differ by n (as used above).
In fact, what you get in C depends on the compiler and architecture, while
Python is always consistent and returns positive remainders.
More info:
http://www.python.org/doc/faq/programming/#why-does-22-10-return-3
http://groups.google.com/group/comp.lang.python/search?group=comp.lang.python&q=modulo+negative+C
Think of clock arithmetic:
/ 0
-1 /
/ 9 1
8 2
7 3
6 4
5
1 step counter-clockwise is the same as 9 steps
clockwise, so -1 is congruent to 9 (mod 10), so both
are correct. A common mistake is to assume -1 and +1
to be the same. Remember, in Python, sequential
negative numbers % n is equivalent to going
counter-clockwise:
>>> for i in xrange(-1,-12,-1):
print i % 12,
11 10 9 8 7 6 5 4 3 2 1
cheers,
Stef
Maybe it is an order-of-operations thing....
-111 % 10 = -1
(-111) % 10 = 9
?
and on the other hand, maybe it's not. Try to think of any language
where unary minus binds so loosely.
Why the theoretical argument when you can TEST your assumptions?
>>> -111 % 10
9
>>> (-111) % 10
9
>>> Second, in Turbo C -111%10=-1 however in python -111%10=9. Is one or
>>> the other in error? Is this a known gotcha? I tried to google the
>>> subject however one cannot google the symbol %. Thanks in advance.
[...]
> In fact, what you get in C depends on the compiler and architecture,
Not according to the C standard:
When integers are divided, the result of the / operator is
the algebraic quotient with any fractional part discarded.(87)
If the quotient a/b is representable, the expression
(a/b)*b + a%b shall equal a.
[...]
87) This is often called ‘‘truncation toward zero’’.
[International Standard ISO/IEC 9899:1999, Section 6.5.5
Multiplicative operators, Paragraph 6 and footnote 87]
> while Python is always consistent and returns positive remainders.
Technically:
The modulo operator always yields a result with the same sign
as its second operand (or zero)
[http://docs.python.org/ref/binary.html]
--
--Bryan
This seems most logical to me. Turbo C is against the standard, then.
> > while Python is always consistent and returns positive remainders.
>
> Technically:
>
> The modulo operator always yields a result with the same sign
> as its second operand (or zero)
>
> [http://docs.python.org/ref/binary.html]
>
Again, logical.
Thanks, Roy. But it's hard to find when one doesn't know it's name!
No, Turbo C is yielding the one-and-only correct result with respect
to the C standard:
(a/b)*b + a%b shall equal a
(-111/10)*10 + -111%10 shall equal -111
(-111/10) evaluates to -11 by the truncate-toward-zero rule
-11*10 + -111%10 shall equal -111
-110 + -111%10 shall equal -111
-111%10 shall equal -1
--
--Bryan
The operator is usually called "mod". (The symbol is usually
called "percent".)
I reserve "modulo" for its usage in mathematics. 70 modulo 6
is an equivalence class containing infinitely many integers.
In math talk, 4 is the least residue of 70 modulo 6.
> Second, in Turbo C -111%10=-1 however in python -111%10=9. Is one or
> the other in error?
Turbo C is correct here with respect to the C standard. Python
is correct with respect to the Python Reference Manual.
They also disagree about integer division. C rounds toward zero;
Python rounds downward.
In C: -111 / 10 evaluates to -11
In Python: -111 / 10 evaluates to -12
> Is this a known gotcha? I tried to google the
> subject however one cannot google the symbol %.
I think it's a known gotcha. I cited the refs in another post.
--
--Bryan
But, in general, doesn't (-11,-4) also satisfy
x = y * a + b
-70 = 6 * -11 + (-4)?
Do you overpay your car loans and wait for a refund?
Or do you make your last payment the residue of the
debt after making 47 (or whatever) equal payments?
>
> IOWs, the definition of modulo, and the definition of integer division,
> are linked...
>
> --
> Wulfraed Dennis Lee Bieber KD6MOG
> wlfr...@ix.netcom.com wulfr...@bestiaria.com
> HTTP://wlfraed.home.netcom.com/
> (Bestiaria Support Staff: web-a...@bestiaria.com)
> HTTP://www.bestiaria.com/
You're probably thinking of Galois *groups*. Some finite Galois
groups are cyclic, so they are of the form Z/nZ that can be described
as {0, .. , n-1}. But Galois groups can have many other forms.
--
Arnaud
The divmod() function is one of those little delights that reminds
me why I love Python, but I do not think it answers the question
here. The definition of divmod() references the '%' operation, and
not the other way around.
http://docs.python.org/lib/built-in-funcs.html
http://docs.python.org/ref/binary.html
>>>> divmod(70, 6)
> (11, 4)
>>>> 6*11 + 4
> 70
>>>> divmod(-70, 6)
> (-12, 2)
>>>> 6 * -12 + 2
> -70
Also:
>>> divmod(70, -6)
(-12, -2)
>>> -6*-12 + -2
70
>>> divmod(-70, -6)
(11, -4)
>>> -6*11 + -4
-70
> Or in general terms
>
> (a, b) = divmod(x, y)
> x = y * a + b
> IOWs, the definition of modulo, and the definition of integer division,
> are linked...
Right. Thus given integers x and y, y!=0, Python and C agree:
x == (y * (x / y)) + (x % y)
The disagreement is how integer division rounds. In C, integer
division rounds toward zero. In Python, integer division rounds
downward.
--
--Bryan
I was *assuming* nothing; I *know* what is the relative precedence of
% and unary minus in both C and Python. I was not arguing; I was
inviting Lee (as I now invite you) to think before writing.
I didn't make an opinion on which was "correct".
> Either
> method allows one to recover the original value from the output of
> divmod.
My point was the need to satisfy x = y * a + b doesn't
explain WHY divmod(-70,6) returns (-12,2) instead of (-11,-4).
>
> Whether that works in the way you intend is a different matter -- my
> car loans usually have interest factors which are applied per payment by
> payment date, so using modulo (or divmod) is not applicable, one must
> actually build the table of payments one at a time (especially since the
> automatic payments taken from paychecks gets "corrupted" during
> holidays, when paychecks are issued a day or two earlier than normal,
> meaning less interest charges during that period and more applied to
> principle; with more on interest the following week, and less on
> interest).
Ok, poor example. Suppose instead we are slicing a 70 character string
from the right. We certainly CAN'T have 6 12-letter slices, can we?
But we can have 6 11-letter slices with 4 characters left over.
And there are probably examples where (-12,2) would make more sense,
although I can't think of one at the moment.
Again, I'm not saying (-12,2) is wrong, just that the explanation
why it's (-12,2) is wanting since there are cases where (-11,-4)
makes more sense.
C, which was designed as a "high level assembly language," does not
tightly define the results of / and % for negative numbers. Instead
it defines the result for positive over positive, and constrains the
result for the others. The reason is simple: most CPUs available
at the time provided a single operation that produced both the quotient
and the remainder, but some produced -1 for -3 / 2, and others produced
1 for -3 / 2. Either result is justifiable, but the most common use
of division and remainder is positive / positive, and it would be a
shame to generate a test for every division and modulus just to cover
the negative / positive case. You would be slowing down the majority
of code to satisfy the (usually non-existant) corner case.
-Scott David Daniels
Scott....@Acm.Org
Call it a known gotcha inherent to integers. In the realm of counts (aka
non-negative integers), there is one sensible definition of division and
modulus (remainder). It has various nice properties. With mixed positive
and negative integers, there are choices, and none have all the nice
properties. The basic problem is that '-infinity' and 0 are in opposite
directions instead of the same direction ;-). Guido made one consistent
choice (which matches some other languages, I believe). Others have made
another consistent choice or no choice at all (leaving the choice to
implementations). I believe I have seen at least one book, if not
language, that defined // and % so that remainders have the same sign as
the numerator. (Or was it denominator?)
tjr
Not true. Here it is again:
When integers are divided, the result of the / operator is
the algebraic quotient with any fractional part discarded.(87)
If the quotient a/b is representable, the expression
(a/b)*b + a%b shall equal a.
[...]
87) This is often called ‘‘truncation toward zero’’.
[International Standard ISO/IEC 9899:1999, Section 6.5.5
Multiplicative operators, Paragraph 6 and footnote 87]
--
--Bryan
In Lisp, we'd say Python implements the mod function and C implements
the rem (remainder) function. See also the functions floor and
truncate:
Cheers,
Cliff
> But C was around for a long time before the 1999 standard. C89,
> commonly called ANSI C, is still very commonly used in compilers, and
> K&R C goes back to 1972. Is truncation toward 0 the standard for K&R C
> as well?
As I remember, the behaviour for negative 'a' wasn't specified in K&R C
or in C89; the rule was tightened up for C99.
-M-
Looks like you have a good point there. I do not have a copy of
the C89 standard, but do I have editions of Harbison&Steele that
reflect the 1989 standard, and they confirm your suspicion that
the results of the '/' and '%' operators on integer operants
were not uniquely defined in cases where an operand could be
negative.
Describing the '/' operator:
For integral operands,, if the mathematical quotient is
is not an exact integer, then the result will be one of
the integers closest to the mathematical quotient of the
operands. Of those two integers, the one closer to 0 must
be chosen if both operands are positive
Furthermore:
It is always true that (a/b)*b + a%b is equal to a if b
is not 0
Quoted from: S. P. Harbison and G. L. Steele. /C: A
Reference Manual, Third Edition/, Prentice Hall, 1991;
Section 7.6.1, page 187.
So Arnau Sanchez and Scott David Daniels were correct with
respect to C89 and older standards, and many implementations
have not yet adopted the 1999 standard that strictly defines
the results of / and %.
--
--Bryan