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

Reply via email to