[Numpy-discussion] Re: Why floor and ceil change the type of the array?

Robert Kern robert.kern at gmail.com
Wed Feb 22 21:11:02 CST 2006


Sasha wrote:
> On 2/22/06, Robert Kern <robert.kern at gmail.com> wrote:
> 
>>Sasha wrote:
>>
>>>... wouldn't it
>>>be more natural if fllor and ceil return the argument unchanged (maybe
>>>a copy) if it is already integer?
>>
>>Only if floor() and ceil() returned integer arrays when given floats as input. I
>>presume there are good reasons for this, since it's the same behavior as the
>>standard C functions.
> 
> C does not have ceil(int).  It has
> 
>        double ceil(double x);
>        float ceilf(float x);
>        long double ceill(long double x);
> 
> and neither of these functions change the type of the argument.

That's exactly what I meant. These functions only apply to integers through
casting to the appropriate float type. That's precisely what numpy.floor() and
numpy.ceil() do.

Actually, I think the reasoning for having the float versions return floats
instead of integers is that an integer-valued double is possibly out of range
for an int or long on some platforms, so it's kept as a float. Since this
obviously isn't a problem if the input is already an integer type, I don't have
any particular objection to making floor() and ceil() return integers if their
inputs are integers.

> Numpy's "around" is a noop on integers (even for decimals<0, but
> that's a different story.

It's also a function and not a ufunc.

> I cannot really think of any reason for the current numpy behaviour
> other than the consistency with transcendental functions. 

It's simply the easiest thing to do with the ufunc machinery.

> Speaking of
> which, can someone explain this:
> 
>>>>sin(array(1,'h')).dtype
> 
> dtype('<f4')
> 
>>>>sin(array(1,'i')).dtype
> 
> dtype('<f8')

AFAICT, the story goes like this: sin() has two implementations, one for
single-precision floats and one for doubles. The ufunc machinery sees the int16
and picks single-precision as the smallest type of the two that can fit an int16
without losing precision. Naturally, you probably want the function to operate
in higher precision, but that's not really information that the ufunc machinery
knows about.

-- 
Robert Kern
robert.kern at gmail.com

"In the fields of hell where the grass grows high
 Are the graves of dreams allowed to die."
  -- Richard Harter





More information about the Numpy-discussion mailing list