Stefan Behnel wrote:
> Dag Sverre Seljebotn, 03.12.2009 12:45:
>> Stefan Behnel wrote:
>>> Dag Sverre Seljebotn, 03.12.2009 10:52:
>>>
>>>>> - Python's floating point type is double, so it should be perfectly
>>>>> safe to do
>>>>>
>>>>> cdef double f(): ...
>>>>> x = f() # infer x as double
>>>>>
>>>>> By the same argument one might actually want to do
>>>>>
>>>>> cdef float f(): ...
>>>>> x = f() # infer x as *double* -- because that's what Python would use
>>>>>
>>> That's actually an orthogonal feature: aliasing Python's float type to C's
>>> double type in general, including support for methods etc. Since 'double'
>>> is immutable and has exactly the same value range as Python's float type,
>>> this is something that can always be done safely. If I'm not mistaken, even
>>> Python's operators behave exactly like the equivalent C operators here,
>>> right? And numeric operations would always return a double, so even
>>> operations on doubles that involve integers would run completely in C space.
>>>
>>> Apart from a couple of further optimisations for methods and properties, I
>>> think enabling type inference here would give us a rather warmly requested
>>> feature.
>>>
>> This is now http://trac.cython.org/cython_trac/ticket/460.
>
> Rethinking this some more, there are a couple of problems with this, e.g.
> overflow errors:
>
> >>> 2.0**1000000
> Traceback (most recent call last):
> OverflowError: (34, 'Numerical result out of range')
>
> Moving this calculation to C space means we have to catch the error and
> raise an exception for it.
Hmm. Only seems like it applies to pow though:
In [23]: 9e307+9e307
Out[23]: inf
At least for Python 2.6.2. Which is a very strange and inconsistent
result to me. 2.0**10000000.0 also gives an exception. I don't quite
have the time to look up the Python specs on this one but it should be
done...
Anyways, my opinion here is:
- Directive to assume we don't go out of range (perhaps bignumbers and
merge with the integer case)
- We should raise exceptions in the same situations as in Python even
for "cdef double"s (re: the integer division isse -- it's just much
easier to learn stuff if we're consistent)
(Long-term, note that floating point exceptions can be raised by
checking flags in the CPU, so that when there's no side-effects, like
z = (x**2 + y**2)**(.5)
we don't have to check to raise an exception before the entire
expression has run. That needs control flow analysis though.)
> Then, while simplistic code like this will work beautifully:
>
> d = 1.0
> for i in range(1000):
> d += 1.0
> print d
>
> most code won't currently benefit from enabling type inference for doubles,
> as it's rather unlikely that all operations done on a variable only use
> other (implicitly/explicitly) typed names as operands. And as long as there
> is one assignment with unknown types on the rhs, the name will be typed as
> Python object (which is required since the value could be anything, e.g.
> some kind of vector object). So we clearly have to do more here to make
> this useful.
Well, when
Two remedies though:
- Support for declaring that e.g. math.sin in returns a double (e.g.
through a math.pxd which is used on a pure Python import..)
- I think there's no way around the fact that users have to care about
types at some boundary points in the program. However I think it is much
friendlier (compatible with pure Python, for one thing) to do e.g.
d = 1.0
for i in range(1000):
d += float(myfunc(i))
which would be enough.
--
Dag Sverre
_______________________________________________
Cython-dev mailing list
[email protected]
http://codespeak.net/mailman/listinfo/cython-dev