In Python, if I write "-1 % 5", I get 4. This is how we do it in Sage
as well (and I think it's the right way--that's not what I'm trying
to ask). However, in C if I write "-1 % 5" I get -1. The question is,
what should I get in Cython if I write (a % b) where a and b are cdef
ints? Should I
[ ] Get 4, because it should behave just like in Python, even though
it will require extra logic and be a bit slower
[ ] Get -1, because they're C ints, and besides we wouldn't be using
Cython if we didn't care about performance
[ ] Let the programmer decide (e.g. using http://wiki.cython.org/
enhancements/compilerdirectives ) recognizing that % will mean
different things in different contexts.
- Robert
In C, ZZ/nZZ does not have canonical representatives. For example,
the equivalent of [n%4 for n in [-7 .. 7]] would give:
-3, -2, -1, 0, -3, -2, -1, 0, 1, 2, 3, 0, 1, 2, 3
This is annoying to a mathematician. The big reason in favor of this
is to align with division: both C and Python give a==(a/b)*b+a%b, but
Python uses floor division and C uses truncating division.
So why does C use truncating division? I'm not sure what the choice
point was, but at this point two very important reasons would be:
because that's what the signed integer division instruction gives you
on basically all processors, and because that's what the C standard
has specified for years, so people have written code depending on that
behavior. Given these facts, it's IMHO unlikely that C will ever
change.
Carl
I've also been reading the Cython thread ... I agree that there's a
good argument for Python semantics, but when it comes down to it, I
think of Cython as "being able to move my inner loops down to C" -- if
I type "cdef int x", I'm generally expecting x to act like a C int,
and be *as fast as humanly possible*. Plus, when we move things from
Python down to Cython, we already have changes to make -- for
instance, x**2 has to change, because C doesn't support
exponentiation, so why would it be any different for %?
That said, it would be really nice if there were an easy way to get
Python semantics for % on C ints. I just don't think it should be the
default.
-cc
I support this because I would like Cython to remain primarily a way
to interface to C code rather than become the "default language of
sage".
Nick
Cython doesn't automatically translate x**2 into x*x or pow(x,2)? If
not, why not?
Thanks,
Jason
There's actually a thread to re-implement this. Originally, Pyrex
translated a**b to pow(a,b) for c ints, which was strange given the
result was a floating point number, so we disabled it. Of course
there's a narrow range of non-overflowing values.
- Robert
Division/modulo was compiler-defined in the original ANSI C, but this
was changed in C99, which specifies truncating division.
Carl
However, all of the letters in C are the same, whereas only 5/6 of the
letters in Python are the same.
Nick
> On 12 Mrz., 16:51, Carl Witty <carl.wi...@gmail.com> wrote:
>> On Thu, Mar 12, 2009 at 4:16 AM, David Joyner <wdjoy...@gmail.com>
>> wrote:
>>
>>> I have an ignorant question: what are the canonical reps of
>>> ZZZ/nZZZ in C? (-n/2,n/2]?
>>> Is the issue to decide between the interval [0,n-1] as reps of ZZ/
>>> nZZ (Python)
>>> vs (-n/2,n/2] (C)?
>>
>> In C, ZZ/nZZ does not have canonical representatives. For example,
>> the equivalent of [n%4 for n in [-7 .. 7]] would give:
>>
>> -3, -2, -1, 0, -3, -2, -1, 0, 1, 2, 3, 0, 1, 2, 3
>
> Hi Carl,
>
> the situation might be worse:
> AFAIK, that choice ist *not* defined by the ANSI C standard, but left
> complier-dependent. In other words: you might get different answers on
> the same system using different C compilers, or even the same C
> compiler with different options. C is fun, isn't it?
Interestingly enough, the Python sources are written to work no
matter what C's behavior.
> So the original question turns into:
> Do we want to (potentially) sacrifice speed in favor of portability?
Yes, I at least want to have that option. Also, on a pragmatic note,
Sage has already been programed with this assumption and I would hate
to slow it down due to language changes.
> If so, we should make the Cython behaviour predictable, i.e. "fixed"
> --- favourably identical to the Python behaviour.
> And in the Cython build scripts we should check whether we have e.g.
> GCC/architecture xyz and set respective options, to not lose speed in
> the cases it is not necessary so.
>
> Cheers,
> gsw
>
>>
>> This is annoying to a mathematician. The big reason in favor of this
>> is to align with division: both C and Python give a==(a/b)*b+a%b, but
>> Python uses floor division and C uses truncating division.
>>
>> So why does C use truncating division? I'm not sure what the choice
>> point was, but at this point two very important reasons would be:
>> because that's what the signed integer division instruction gives you
>> on basically all processors, and because that's what the C standard
>> has specified for years, so people have written code depending on
>> that
>> behavior. Given these facts, it's IMHO unlikely that C will ever
>> change.
I would guess C does truncating division because it's easier--one
just performs the unsigned division and copies the sign over.
- Robert
I just knew someone would say that. I also thought someone would say
that the "C" comes first in the word...
Jason