Exemple #1
0
static PyObject *
GMPy_Complex_Rect(PyObject *x, PyObject *y, CTXT_Object *context)
{
    MPFR_Object *tempx, *tempy;
    MPC_Object *result;

    CHECK_CONTEXT(context);

    tempx = GMPy_MPFR_From_Real(x, 1, context);
    tempy = GMPy_MPFR_From_Real(y, 1, context);
    result = GMPy_MPC_New(0, 0, context);
    if (!tempx || !tempy || !result) {
        Py_XDECREF((PyObject*)tempx);
        Py_XDECREF((PyObject*)tempy);
        Py_XDECREF((PyObject*)result);
        return NULL;
    }

    mpfr_cos(mpc_realref(result->c), tempy->f, GET_REAL_ROUND(context));
    mpfr_mul(mpc_realref(result->c), mpc_realref(result->c), tempx->f, GET_REAL_ROUND(context));
    mpfr_sin(mpc_imagref(result->c), tempy->f, GET_IMAG_ROUND(context));
    mpfr_mul(mpc_imagref(result->c), mpc_imagref(result->c), tempx->f, GET_IMAG_ROUND(context));
    Py_DECREF((PyObject*)tempx);
    Py_DECREF((PyObject*)tempy);

    GMPY_MPC_CLEANUP(result, context, "rect()");
    return (PyObject*)result;
}
static PyObject *
GMPy_PyComplex_From_MPC(PyObject *self, PyObject *other)
{
    CTXT_Object *context = NULL;
    double real, imag;

    CHECK_CONTEXT(context);

    real = mpfr_get_d(mpc_realref(MPC(self)), GET_REAL_ROUND(context));
    imag = mpfr_get_d(mpc_imagref(MPC(self)), GET_IMAG_ROUND(context));

    return PyComplex_FromDoubles(real, imag);
}
static MPC_Object *
GMPy_MPC_From_Decimal(PyObject *obj, mpfr_prec_t rprec, mpfr_prec_t iprec,
                      CTXT_Object *context)
{
    MPC_Object *result = NULL;
    MPFR_Object *tempf;
    mpfr_prec_t oldmpfr, oldreal;
    int oldmpfr_round, oldreal_round;

    assert(IS_DECIMAL(obj));

    CHECK_CONTEXT(context);

    oldmpfr = GET_MPFR_PREC(context);
    oldreal = GET_REAL_PREC(context);
    oldmpfr_round = GET_MPFR_ROUND(context);
    oldreal_round = GET_REAL_ROUND(context);

    context->ctx.mpfr_prec = oldreal;
    context->ctx.mpfr_round = oldreal_round;

    tempf = GMPy_MPFR_From_Decimal(obj, rprec, context);

    context->ctx.mpfr_prec = oldmpfr;
    context->ctx.mpfr_round = oldmpfr_round;

    result = GMPy_MPC_New(0, 0, context);
    if (!tempf || !result) {
        Py_XDECREF((PyObject*)tempf);
        Py_XDECREF((PyObject*)result);
        return NULL;
    }

    result->rc = MPC_INEX(tempf->rc, 0);
    mpfr_swap(mpc_realref(result->c), tempf->f);
    Py_DECREF(tempf);
    return result;
}
static MPC_Object *
GMPy_MPC_From_PyStr(PyObject *s, int base, mpfr_prec_t rprec, mpfr_prec_t iprec,
                    CTXT_Object *context)
{
    MPC_Object *result;
    PyObject *ascii_str = NULL;
    Py_ssize_t len;
    char *cp, *unwind, *tempchar, *lastchar;
    int firstp = 0, lastp = 0, real_rc = 0, imag_rc = 0;

    CHECK_CONTEXT(context);

    if (PyBytes_Check(s)) {
        len = PyBytes_Size(s);
        cp = (char*)PyBytes_AsString(s);
    }
    else if (PyUnicode_Check(s)) {
        ascii_str = PyUnicode_AsASCIIString(s);
        if (!ascii_str) {
            VALUE_ERROR("string contains non-ASCII characters");
            return NULL;
        }
        len = PyBytes_Size(ascii_str);
        cp = (char*)PyBytes_AsString(ascii_str);
    }
    else {
        TYPE_ERROR("string required");
        return NULL;
    }

    /* Don't allow NULL characters */
    if (strlen(cp) != len) {
        VALUE_ERROR("string without NULL characters expected");
        Py_XDECREF(ascii_str);
        return NULL;
    }

    if (!(result = GMPy_MPC_New(rprec, iprec, context))) {
        Py_XDECREF(ascii_str);
        return NULL;
    }

    /* Get a pointer to the last valid character (ignoring trailing
     * whitespace.) */
    lastchar = cp + len - 1;
    while (isspace(*lastchar))
        lastchar--;

    /* Skip trailing ). */
    if (*lastchar == ')') {
        lastp = 1;
        lastchar--;
    }

    /* Skip trailing j. */
    if (*lastchar == 'j')
        lastchar--;

    /* Skip leading whitespace. */
    while (isspace(*cp))
        cp++;

    /* Skip a leading (. */
    if (*cp == '(') {
        firstp = 1;
        cp++;
    }

    if (firstp != lastp) goto invalid_string;

    /* Read the real component first. */
    unwind = cp;
    real_rc = mpfr_strtofr(mpc_realref(result->c), cp, &tempchar, base,
                           GET_REAL_ROUND(context));

    /* Verify that at least one valid character was read. */
    if (cp == tempchar) goto invalid_string;

    /* If the next character is a j, then the real component is 0 and
     * we just read the imaginary componenet.
     */
    if (*tempchar == 'j') {
        mpfr_set_zero(mpc_realref(result->c), MPFR_RNDN);
        cp = unwind;
    }
    else {
        /* Read the imaginary component next. */
        cp = tempchar;
    }

    imag_rc = mpfr_strtofr(mpc_imagref(result->c), cp, &tempchar, base,
                           GET_IMAG_ROUND(context));

    if (cp == tempchar && tempchar > lastchar)
        goto valid_string;

    if (*tempchar != 'j' && *cp != ' ')
        goto invalid_string;

    if (tempchar <= lastchar)
        goto invalid_string;

  valid_string:
    Py_XDECREF(ascii_str);
    result->rc = MPC_INEX(real_rc, imag_rc);

    if (rprec != 1 || iprec != 1) {
        GMPY_MPC_CHECK_RANGE(result, context);
    }
    GMPY_MPC_SUBNORMALIZE(result, context);
    GMPY_MPC_EXCEPTIONS(result, context);

    return result;

  invalid_string:
    VALUE_ERROR("invalid string in mpc()");
    Py_DECREF((PyObject*)result);
    Py_XDECREF(ascii_str);
    return NULL;
}