tiny extension crashes

Greg Jorgensen gregj at pobox.com
Wed Mar 14 23:52:47 EST 2001


You have an uninitialized pointer, intp, in your iround() function. Do this:

double intp;
...
if (fabs(modf(number, &intp)) >= 0.5) {
        intp >= 0 ? (intp)++ : (intp)--;
...
return Py_BuildValue("l", (long)intp);

But you don't need to do so much work with the floating-point functions to
round a number. Just add +/- 0.5 and truncate. Converting a float or double
to an int or long will truncate the fractional portion.

double number;
long intp;

if (PyArg_ParseTuple(args, "d", &number)) {
    intp = (number > 0.0) ? (number + 0.5) : (number - 0.5);
    return Py_BuildValue("l", intp);
}
else
    return NULL;


Since you posted your source code, let me suggest an alternative
implementation of array_max:

static long array_max(PyArrayObject *array, int absolute)
{
    long *a = array->data;
    long stride = array->strides[0];
    long max = 0;

    if (absolute) {
        for (i = 0; i < array->dimensions[0]; i++) {
            if (labs(*a) > max)
                max = labs(*a);
            a += stride;
        }
    }
    else {
        for (i = 0; i < array->dimensions[0]; i++) {
            if (*a > max)
                max = *a;
            a += stride;
        }
    }
    return max;
}

The test on absolute only happens once, not at every loop iteration. (I
would make this two functions, one that works on the actual values and one
that works on the absolute values.) The array->data[] index calculation is
changed to pointer addition. And I used the labs() function rather than the
unnecessary floating-point fabs() version. And I changed max to a long, and
made the function return a long.

--
Greg Jorgensen
PDXperts
Portland, Oregon, USA
gregj at pobox.com





More information about the Python-list mailing list