From: arcege at shore.net (Michael P. Reilly)
Date: Mon, 12 Apr 1999 17:56:33 GMT
Subject: extending questions
References: <371220AD.6C3B0B5@home.com>
Message-ID: <ltqQ2.383$Ij2.44245@news.shore.net>
Content-Length: 1985
X-UID: 1434                                                  

Jim Meier <fatjim at home.com> wrote:
: I have two questions, one simple, one a little bit whiny.

: Firstly, I'm looking for a quick and easy way for a PyCFunction to
: accept as an argument either an integer or a floating point number, so
: that the function can be called as

:   func(1,1,1)

: or as

:   func(0.5,0,2/3)

: because python doesn't seem to let me consider an integer as a float.
: I've tried using some of the conversion functions in the abstract
: numeric suite and the PyFloat_GetDouble (or some similar name), but with
: no luck - it always returned -1 for me. Any ideas?

My best suggestion would be to use the PyInt_Check and PyFloat_check
functions.

  PyObject *func(PyObject *self, PyObject *args)
    { PyObject *arg1, *arg2, *arg3;
      double a1, a2, a3;

      if (!PyArg_ParseTuple(args, "OOO", &arg1, &arg2, &arg3))
        return NULL;
      /* get the double from the first argument */
#define py_to_double(a, var) \
      if (PyInt_Check(a)) (var) = (double)PyInt_AS_LONG(a); \
      else if (PyFloat_Check(a)) (var) = PyFloat_AS_DOUBLE(a); \
      else { PyErr_SetString(PyExc_TypeError, "must supply a number"); \
        return NULL; }

      py_to_double(arg1, a1);
      py_to_double(arg2, a2);
      py_to_double(arg3, a3);
#undef py_to_double

: Also, ust a suggestion, but would it be possible to add a
: PyNumber_GetDouble(PyObject*n) function to the absract numberic
: interface? This would be useful for this sort of situation.

There already is a PyNumber_Float(PyObject *) function;  since the
purpose of the PyNumber_* functions is to make abstract numbers (classes,
builtins, etc.), you don't want to assume it is a double, but to
coerce it into a double.

  PyObject *temp;
  double result;

  if ((temp = PyNumber_Float(number)) != NULL) {
    result = PyFloat_AS_DOUBLE(temp);
    Py_DECREF(temp);
  } else
    return NULL;

This is the same as "result = float(number)" in python, except that you
get the C result.

  -Arcege





