Beispiel #1
0
static PyObject *
GMPy_MPFR_Mod_Slot(PyObject *x, PyObject *y)
{
    if (IS_REAL(x) && IS_REAL(y))
        return GMPy_Real_Mod(x, y, NULL);

    if (IS_COMPLEX(x) && IS_COMPLEX(y))
        return GMPy_Complex_Mod(x, y, NULL);

    Py_RETURN_NOTIMPLEMENTED;
}
Beispiel #2
0
int cksiz(QSP_ARG_DECL  int argtyp,Data_Obj *src_dp,Data_Obj *dst_dp)
{
	int i;

	/* allow exception for vmaxg, etc.
	 * These functions return two scalars, the max value,
	 * and number of occurrences, PLUS a vector with the
	 * indices of the occurrences.
	 *
	 * But where do we check them?  Do we need to do any checking for them?
	 */
	if( argtyp == V_SCALRET2 )
		return(0);

	for(i=0;i<N_DIMENSIONS;i++){
		if( OBJ_TYPE_DIM(src_dp,i) != OBJ_TYPE_DIM(dst_dp,i) ){

			/* special case for real/cpx fft */
			if( i==1 ){
				if( (argtyp & FWD_FT) && IS_REAL(src_dp) && IS_COMPLEX(dst_dp) ){
					if( OBJ_COLS(dst_dp) == (1+OBJ_COLS(src_dp)/2) )
						continue;
				} else if( (argtyp & INV_FT) && IS_COMPLEX(src_dp) && IS_REAL(dst_dp) ){
					if( OBJ_COLS(src_dp) == (1+OBJ_COLS(dst_dp)/2) )
						continue;
				}
			}

			/* if we get to here, the dimensions don't match... */
			/* if the source dimension is 1, it may be an outer op */
			/* if the destination dimension is 1, it may be a projection op */
			if( OBJ_TYPE_DIM(src_dp,i) == 1 /* && (argtyp&VV_SOURCES) == VV_SOURCES */ ){
				/* vmul, vadd, vsub, vatan2 */
				/* vvm_gt etc also */
				/* don't need VV_SOURCES... */
				continue;
			} else if( OBJ_TYPE_DIM(dst_dp,i) == 1 && CAN_PROJECT(argtyp) ){
				/* vsum, vmaxv, vmainv, etc */
				continue;
			} else {
				/* if we get to here, we're not happy... */
				sprintf(ERROR_STRING,
					"cksiz:  %s count mismatch, %s (%d) & %s (%d)",
					dimension_name[i],
					OBJ_NAME(src_dp),OBJ_TYPE_DIM(src_dp,i),
					OBJ_NAME(dst_dp),OBJ_TYPE_DIM(dst_dp,i));
				WARN(ERROR_STRING);
				return(-1);
			}
		}
	}
	return(0);
} /* end cksiz() */
Beispiel #3
0
static PyObject *
GMPy_MPQ_Add_Slot(PyObject *x, PyObject *y)
{
    if (IS_RATIONAL(x) && IS_RATIONAL(y))
        return GMPy_Rational_Add(x, y, NULL);

    if (IS_REAL(x) && IS_REAL(y))
        return GMPy_Real_Add(x, y, NULL);

    if (IS_COMPLEX(x) && IS_COMPLEX(y))
        return GMPy_Complex_Add(x, y, NULL);

    Py_RETURN_NOTIMPLEMENTED;
}
Beispiel #4
0
enum error
become_integer(Var in, Num *ret, int called_from_tonum)
{
    switch (in.type) {
    case TYPE_INT:
	*ret = in.v.num;
	break;
    case TYPE_STR:
	if (!(called_from_tonum
	      ? parse_number(in.v.str, ret, 1)
	      : parse_object(in.v.str, ret)))
	    *ret = 0;
	break;
    case TYPE_OBJ:
	*ret = in.v.obj;
	break;
    case TYPE_ERR:
	*ret = in.v.err;
	break;
    case TYPE_FLOAT:
        if (!IS_REAL(in.v.fnum))
	    return E_FLOAT;
	*ret = (Num) in.v.fnum;
	break;
    default:
	return E_TYPE;
    }
    return E_NONE;
}
Beispiel #5
0
static enum error
become_float(Var in, double *ret)
{
    switch (in.type) {
    case TYPE_INT:
	*ret = (double) in.v.num;
	break;
    case TYPE_STR:
	if (!parse_float(in.v.str, ret) || !IS_REAL(*ret))
	    return E_INVARG;
	break;
    case TYPE_OBJ:
	*ret = (double) in.v.obj;
	break;
    case TYPE_ERR:
	*ret = (double) in.v.err;
	break;
    case TYPE_FLOAT:
	*ret = *in.v.fnum;
	break;
    case TYPE_LIST:
    case TYPE_HASH:
	return E_TYPE;
    default:
	errlog("BECOME_FLOAT: Impossible var type: %d\n", (int) in.type);
    }
    return E_NONE;
}
Beispiel #6
0
static int _real_cpx_objs_ok( QSP_ARG_DECL  Data_Obj *real_dp,Data_Obj *cpx_dp, const char *funcname )
{
	if( ! IS_COMPLEX(cpx_dp) ){
		sprintf(ERROR_STRING,
			"%s:  %s must be complex",funcname,OBJ_NAME(cpx_dp));
		WARN(ERROR_STRING);
		return FALSE;
	}
	if( ! IS_REAL(real_dp) ){
		sprintf(ERROR_STRING,
			"%s:  %s must be real",funcname,OBJ_NAME(real_dp));
		WARN(ERROR_STRING);
		return FALSE;
	}
	if( ! FLOATING_OBJ( cpx_dp ) ){
		sprintf(ERROR_STRING,
			"%s:  precision must be float or double",funcname);
		WARN(ERROR_STRING);
		return FALSE;
	}

	if( !dp_same_mach_prec(cpx_dp,real_dp,funcname) ){
		sprintf(ERROR_STRING,
	"%s:  complex object (%s,%s) and target (%s,%s) must have same precision",
			funcname,OBJ_NAME(cpx_dp),OBJ_MACH_PREC_NAME(cpx_dp),
			OBJ_NAME(real_dp),OBJ_MACH_PREC_NAME(real_dp));
		WARN(ERROR_STRING);
		return FALSE;
	}
	return TRUE;
}
Beispiel #7
0
static enum error
become_float(Var in, double *ret)
{
    switch (in.type) {
    case TYPE_INT:
	*ret = (double) in.v.num;
	break;
    case TYPE_STR:
	if (!parse_float(in.v.str, ret) || !IS_REAL(*ret))
	    return E_INVARG;
	break;
    case TYPE_OBJ:
	*ret = (double) in.v.obj;
	break;
    case TYPE_ERR:
	*ret = (double) in.v.err;
	break;
    case TYPE_FLOAT:
	*ret = in.v.fnum;
	break;
    default:
	return E_TYPE;
    }
    return E_NONE;
}
Beispiel #8
0
static PyObject *
GMPy_MPANY_Pow_Slot(PyObject *base, PyObject *exp, PyObject *mod)
{
    if (IS_INTEGER(base) && IS_INTEGER(exp))
        return GMPy_Integer_Pow(base, exp, mod, NULL);

    if (IS_RATIONAL(base) && IS_RATIONAL(exp))
        return GMPy_Rational_Pow(base, exp, mod, NULL);

    if (IS_REAL(base) && IS_REAL(exp))
        return GMPy_Real_Pow(base, exp, mod, NULL);

    if (IS_COMPLEX(base) && IS_COMPLEX(exp))
        return GMPy_Complex_Pow(base, exp, mod, NULL);

    Py_RETURN_NOTIMPLEMENTED;
}
Beispiel #9
0
static PyObject *
GMPy_MPZ_Mod_Slot(PyObject *x, PyObject *y)
{
    if (IS_INTEGER(x) && IS_INTEGER(y))
        return GMPy_Integer_Mod(x, y, NULL);

    if (IS_RATIONAL(x) && IS_RATIONAL(y))
        return GMPy_Rational_Mod(x, y, NULL);

    if (IS_REAL(x) && IS_REAL(y))
        return GMPy_Real_Mod(x, y, NULL);

    if (IS_COMPLEX(x) && IS_COMPLEX(y))
        return GMPy_Complex_Mod(x, y, NULL);

    Py_RETURN_NOTIMPLEMENTED;
}
Beispiel #10
0
static PyObject *
GMPy_Number_Add(PyObject *x, PyObject *y, CTXT_Object *context)
{
    if (IS_INTEGER(x) && IS_INTEGER(y))
        return GMPy_Integer_Add(x, y, context);

    if (IS_RATIONAL(x) && IS_RATIONAL(y))
        return GMPy_Rational_Add(x, y, context);

    if (IS_REAL(x) && IS_REAL(y))
        return GMPy_Real_Add(x, y, context);

    if (IS_COMPLEX(x) && IS_COMPLEX(y))
        return GMPy_Complex_Add(x, y, context);

    TYPE_ERROR("add() argument type not supported");
    return NULL;
}
Beispiel #11
0
static PyObject *
GMPy_Number_Round2(PyObject *x, PyObject *y, CTXT_Object *context)
{
    if (IS_REAL(x) && (!y || PyIntOrLong_Check(y)))
        return GMPy_Real_Round2(x, y, context);

    TYPE_ERROR("round2() argument type not supported");
    return NULL;
}
Beispiel #12
0
/*
 * Calculate airspeed as a function of GPS groundspeed and vehicle attitude.
 *  From "IMU Wind Estimation (Theory)", by William Premerlani.
 *  The idea is that V_gps=V_air+V_wind. If we assume wind constant, =>
 *  V_gps_2-V_gps_1 = (V_air_2+V_wind_2) -(V_air_1+V_wind_1) = V_air_2 - V_air_1.
 *  If we assume airspeed constant, => V_gps_2-V_gps_1 = |V|*(f_2 - f1),
 *  where "f" is the fuselage vector in earth coordinates.
 *  We then solve for |V| = |V_gps_2-V_gps_1|/ |f_2 - f1|.
 */
void gps_airspeedGet(AirspeedSensorData *airspeedData, AirspeedSettingsData *airspeedSettings)
{
    float Rbe[3][3];

    {   // Scoping to save memory. We really just need Rbe.
        AttitudeStateData attData;
        AttitudeStateGet(&attData);

        float q[4] = { attData.q1, attData.q2, attData.q3, attData.q4 };

        // Calculate rotation matrix
        Quaternion2R(q, Rbe);
    }

    // Calculate the cos(angle) between the two fuselage basis vectors
    float cosDiff = (Rbe[0][0] * gps->RbeCol1_old[0]) + (Rbe[0][1] * gps->RbeCol1_old[1]) + (Rbe[0][2] * gps->RbeCol1_old[2]);

    // If there's more than a 5 degree difference between two fuselage measurements, then we have sufficient delta to continue.
    if (fabsf(cosDiff) < cosf(DEG2RAD(5.0f))) {
        VelocityStateData gpsVelData;
        VelocityStateGet(&gpsVelData);

        if (gpsVelData.North * gpsVelData.North + gpsVelData.East * gpsVelData.East + gpsVelData.Down * gpsVelData.Down < 1.0f) {
            airspeedData->CalibratedAirspeed = 0;
            airspeedData->SensorConnected    = AIRSPEEDSENSOR_SENSORCONNECTED_FALSE;
            return; // do not calculate if gps velocity is insufficient...
        }

        // Calculate the norm^2 of the difference between the two GPS vectors
        float normDiffGPS2 = powf(gpsVelData.North - gps->gpsVelOld_N, 2.0f) + powf(gpsVelData.East - gps->gpsVelOld_E, 2.0f) + powf(gpsVelData.Down - gps->gpsVelOld_D, 2.0f);

        // Calculate the norm^2 of the difference between the two fuselage vectors
        float normDiffAttitude2 = powf(Rbe[0][0] - gps->RbeCol1_old[0], 2.0f) + powf(Rbe[0][1] - gps->RbeCol1_old[1], 2.0f) + powf(Rbe[0][2] - gps->RbeCol1_old[2], 2.0f);

        // Airspeed magnitude is the ratio between the two difference norms
        float airspeed = sqrtf(normDiffGPS2 / normDiffAttitude2);
        if (!IS_REAL(airspeedData->CalibratedAirspeed)) {
            airspeedData->CalibratedAirspeed = 0;
            airspeedData->SensorConnected    = AIRSPEEDSENSOR_SENSORCONNECTED_FALSE;
        } else {
            // need a low pass filter to filter out spikes in non coordinated maneuvers
            airspeedData->CalibratedAirspeed = (1.0f - airspeedSettings->GroundSpeedBasedEstimationLowPassAlpha) * gps->oldAirspeed + airspeedSettings->GroundSpeedBasedEstimationLowPassAlpha * airspeed;
            gps->oldAirspeed = airspeedData->CalibratedAirspeed;
            airspeedData->SensorConnected    = AIRSPEEDSENSOR_SENSORCONNECTED_TRUE;
        }

        // Save old variables for next pass
        gps->gpsVelOld_N    = gpsVelData.North;
        gps->gpsVelOld_E    = gpsVelData.East;
        gps->gpsVelOld_D    = gpsVelData.Down;

        gps->RbeCol1_old[0] = Rbe[0][0];
        gps->RbeCol1_old[1] = Rbe[0][1];
        gps->RbeCol1_old[2] = Rbe[0][2];
    }
}
Beispiel #13
0
static PyObject *
GMPy_Context_Digits(PyObject *self, PyObject *args)
{
    PyObject *arg0, *tuple, *temp, *result;
    Py_ssize_t argc;

    argc = PyTuple_GET_SIZE(args);
    if (argc == 0) {
        TYPE_ERROR("digits() requires at least one argument");
        return NULL;
    }

    if (argc > 3) {
        TYPE_ERROR("digits() accepts at most three arguments");
        return NULL;
    }

    arg0 = PyTuple_GET_ITEM(args, 0);
    if (!(tuple = PyTuple_GetSlice(args, 1, argc))) {
        return NULL;
    }

    if (IS_INTEGER(arg0)) {
        temp = (PyObject*)GMPy_MPZ_From_Integer(arg0, NULL);
        result = GMPy_MPZ_Digits_Method(temp, tuple);
        Py_DECREF(temp);
        Py_DECREF(tuple);
        return result;
    }
    if (IS_RATIONAL(arg0)) {
        temp = (PyObject*)GMPy_MPQ_From_Rational(arg0, NULL);
        result = GMPy_MPQ_Digits_Method(temp, tuple);
        Py_DECREF(temp);
        Py_DECREF(tuple);
        return result;
    }
    if (IS_REAL(arg0)) {
        temp = (PyObject*)GMPy_MPFR_From_Real(arg0, 1, NULL);
        result = GMPy_MPFR_Digits_Method(temp, tuple);
        Py_DECREF(temp);
        Py_DECREF(tuple);
        return result;
    }
    if (IS_COMPLEX(arg0)) {
        temp = (PyObject*)GMPy_MPC_From_Complex(arg0, 1, 1, NULL);
        result = GMPy_MPC_Digits_Method(temp, tuple);
        Py_DECREF(temp);
        Py_DECREF(tuple);
        return result;
    }

    TYPE_ERROR("digits() argument type not supported");
    return NULL;
}
Beispiel #14
0
static PyObject *
GMPy_Number_Mul_2exp(PyObject *x, PyObject *y, CTXT_Object *context)
{
    if (IS_REAL(x))
        return GMPy_Real_Mul_2exp(x, y, context);

    if (IS_COMPLEX(x))
        return GMPy_Complex_Mul_2exp(x, y, context);

    TYPE_ERROR("mul_2exp() argument type not supported");
    return NULL;
}
Beispiel #15
0
static void _dump(VALUE v, int level) {
	char **symbols;
	void *symbols_buffer[1];
	VALUE *ptr;
	size_t i;
	HASH_OBJECT_ENTRY *e;
	HASH_OBJECT_ENTRY **buckets;

	if(IS_NULL(v))  { printf("%*s* null\n",    level << 1, ""); goto exit; }
	if(IS_TRUE(v))  { printf("%*s* true\n",    level << 1, ""); goto exit; }
	if(IS_FALSE(v)) { printf("%*s* false\n",   level << 1, ""); goto exit; }
	if(IS_UNDEF(v)) { printf("%*s* undef\n",   level << 1, ""); goto exit; }
	if(IS_KWARGS_MARKER(v)){ printf("%*s* kwargs marker\n",   level << 1, ""); goto exit; }

	if(IS_INT(v))   { printf("%*s* int %" VALUE_NUM_FMT "\n", level << 1, "", GET_INT(v)); goto exit; }
	if(IS_REAL(v))  { printf("%*s* real %g\n", level << 1, "", REAL_OBJECT_VAL(v)); goto exit; }

	if(IS_STRING(v)) {
		// TODO: properly handle
		//       1. non-printable characters
		//       2. zero character
		printf("%*s* string(len=%zu) %.*s\n", level << 1, "", OBJ_LEN(v), (int) OBJ_LEN(v), (char *)OBJ_DATA_PTR(v));
		goto exit;
	}

	if(IS_NATIVE_METHOD(v)) {
		symbols_buffer[0] = OBJ_DATA_PTR(v);
		symbols = backtrace_symbols(symbols_buffer, 1);
		printf("%*s* native method %s at %p req_params=%d\n", level << 1, "", symbols[0], OBJ_DATA_PTR(v), NATIVE_METHOD_OBJ_N_REQ_PAR(v));
		for(i=0; i<NATIVE_METHOD_OBJ_N_REQ_PAR(v); i++) {
			printf("%*s* required parameter %zu\n", (level+1) << 1, "", i+1);
			_dump(NATIVE_METHOD_OBJ_PARAMS(v)[i*2+0], level+2);
			_dump(NATIVE_METHOD_OBJ_PARAMS(v)[i*2+1], level+2);
		}
		goto exit;
	}

	if(IS_CLOSURE(v)) {
		printf("%*s* closure name=%s ip=%zu locals_including_params=%d req_params=%d opt_params=%d n_uplevels=%d params_flags=%d\n", level << 1, "",
			IS_NULL(CLOSURE_OBJ_NAME(v)) ? "(none)" : obj_to_cstring(CLOSURE_OBJ_NAME(v)),
			CLOSURE_OBJ_IP(v),
			CLOSURE_OBJ_N_LOCALS(v),
			CLOSURE_OBJ_N_REQ_PAR(v),
			CLOSURE_OBJ_N_OPT_PAR(v),
			CLOSURE_OBJ_N_UPLEVELS(v),
			CLOSURE_OBJ_PARAMS_FLAGS(v)
		);
		for(i=0; i<CLOSURE_OBJ_N_REQ_PAR(v); i++) {
			printf("%*s* required parameter %zu (name and type follow)\n", (level+1) << 1, "", i+1);
			_dump(CLOSURE_OBJ_PARAMS(v)[i*2+0], level+2);
			_dump(CLOSURE_OBJ_PARAMS(v)[i*2+1], level+2);
		}
		for(i=0; i<CLOSURE_OBJ_N_OPT_PAR(v); i++) {
			printf("%*s* optional parameter %zu (name, type and default value follow)\n", (level+1) << 1, "", i+1);
			_dump(CLOSURE_OBJ_PARAMS(v)[CLOSURE_OBJ_N_REQ_PAR(v)*2 + i*3 + 0], level+2);
			_dump(CLOSURE_OBJ_PARAMS(v)[CLOSURE_OBJ_N_REQ_PAR(v)*2 + i*3 + 1], level+2);
			_dump(CLOSURE_OBJ_PARAMS(v)[CLOSURE_OBJ_N_REQ_PAR(v)*2 + i*3 + 2], level+2);
		}
		i = CLOSURE_OBJ_N_REQ_PAR(v)*2 + CLOSURE_OBJ_N_OPT_PAR(v)*3;
		if(CLOSURE_OBJ_PARAMS_FLAGS(v) & PARAMS_FLAG_ARR_SPLAT) {
			printf("%*s* array splat parameter\n", (level+1) << 1, "");
			_dump(CLOSURE_OBJ_PARAMS(v)[i+0], level+2);
			_dump(CLOSURE_OBJ_PARAMS(v)[i+1], level+2);
			i+=3;
		}
		if(CLOSURE_OBJ_PARAMS_FLAGS(v) & PARAMS_FLAG_HASH_SPLAT) {
			printf("%*s* hash splat parameter\n", (level+1) << 1, "");
			_dump(CLOSURE_OBJ_PARAMS(v)[i+0], level+2);
			_dump(CLOSURE_OBJ_PARAMS(v)[i+1], level+2);
			i+=3;
		}
		goto exit;
	}

	if(IS_ARRAY(v)) {
		printf("%*s* array of length %zu\n", level << 1, "", OBJ_LEN(v));
		for(i=0, ptr=(VALUE *)OBJ_DATA_PTR(v); i<OBJ_LEN(v); i++, ptr++) {
			_dump(*ptr, level+1);
		}
		goto exit;
	}

	if(IS_HASH(v)) {
		printf("%*s* hash with total of %zu items in %zu buckets at %p\n", level << 1, "", OBJ_LEN(v), HASH_BUCKETS_N(v), OBJ_DATA_PTR(v));
		buckets = OBJ_DATA_PTR(v);
		for(i=0; i<HASH_BUCKETS_N(v); i++) {
			if(!buckets[i]) { continue; }
			printf("%*s* bucket # %zu\n", (level+1) << 1, "", i);
			for(e=buckets[i]; e; e=e->bucket_next) {
				printf("%*s* item at %p with hash() of %u insertion_order_prev=%p insertion_order_next=%p \n", (level+2) << 1, "", (void *)e, e->hash, (void *)e->insertion_order_prev, (void *)e->insertion_order_next);
				printf("%*s* key\n", (level+3) << 1, "");
				_dump(e->key, level+4);
				printf("%*s* value\n", (level+3) << 1, "");
				_dump(e->val, level+4);
			}
		}
		goto exit;
	}

	if(IS_NGS_TYPE(v)) {
		printf("%*s* type (name and optionally constructors and parents follow) id=%" PRIdPTR " ptr=%p\n", level << 1, "", NGS_TYPE_ID(v), IS_NORMAL_TYPE(v) ? v.ptr : 0);
		_dump(NGS_TYPE_NAME(v), level + 1);
		if(level < 3) {
			_dump(NGS_TYPE_FIELDS(v), level + 1);
			_dump(NGS_TYPE_CONSTRUCTORS(v), level + 1);
			_dump(NGS_TYPE_PARENTS(v), level + 1);
		}
		goto exit;
	}

	if(IS_CLIB(v)) {
		printf("%*s* C library (name follows) ptr=%p\n", level << 1, "", OBJ_DATA_PTR(v));
		_dump(CLIB_OBJECT_NAME(v), level + 1);
		goto exit;
	}

	if(IS_CSYM(v)) {
		printf("%*s* C symbol (name and libraray follow) ptr=%p\n", level << 1, "", OBJ_DATA_PTR(v));
		_dump(CSYM_OBJECT_NAME(v), level + 1);
		_dump(CSYM_OBJECT_LIB(v), level + 1);
		goto exit;
	}

	if(IS_NORMAL_TYPE_CONSTRUCTOR(v)) {
		printf("%*s* user type constructor (type optionally follows)\n", level << 1, "");
		if(level < 3) {
			_dump(OBJ_DATA(v), level + 1);
		}
		goto exit;
	}

	if(IS_NORMAL_TYPE_INSTANCE(v)) {
		printf("%*s* user type instance (type and fields optionally follow)\n", level << 1, "");
		// level < 4 so that uncaught exception ImplNotFound could display the type of the arguments
		if(level < 4) {
			_dump(NORMAL_TYPE_INSTANCE_TYPE(v), level + 1);
			_dump(NORMAL_TYPE_INSTANCE_FIELDS(v), level + 1);
		}
		goto exit;
	}

	printf("%*s* (dump not implemented for the object at %p)\n", level << 1, "", OBJ_DATA_PTR(v));

exit:
	return;
}
Beispiel #16
0
static int GMPy_isReal(PyObject *obj)
{
    return IS_REAL(obj) ? 1 : 0;
}
Beispiel #17
0
void execute_function(VM *vm) {
restart: {
    Frame *frame = vm->current;
    Closure *closure = frame->closure;
    Chunk *chunk = closure->chunk;
    StackObject *registers = frame->registers;

    while (frame->pc < chunk->numinstructions) {
        int instruction = chunk->instructions[frame->pc];

        OpCode o = GET_O(instruction);
        int a = GET_A(instruction);
        int b = GET_B(instruction);
        int c = GET_C(instruction);

        switch (o) {
            case OP_MOVE:
            {
                if (b < 256) {
                    copy_object(&registers[a], &registers[b]);
                } else {
                    copy_constant(vm, &registers[a], chunk->constants[b - 256]);
                }
            } break;

            case OP_GETUPVAR:
            {
                Upval *upval = closure->upvals[b];

                if (!upval->open) {
                    // upval is closed
                    copy_object(&registers[a], upval->data.o);
                } else {
                    // still on stack
                    copy_object(&registers[a], &upval->data.ref.frame->registers[upval->data.ref.slot]);
                }
            } break;

            case OP_SETUPVAR:
            {
                Upval *upval = closure->upvals[b];

                if (!upval->open) {
                    // upval is closed
                    copy_object(upval->data.o, &registers[a]);
                } else {
                    // still on stack
                    copy_object(&upval->data.ref.frame->registers[upval->data.ref.slot], &registers[a]);
                }
            } break;

            case OP_ADD:
            {
                // TODO - make string coercion better
                // TODO - make string type with special operators

                if (IS_STR(b) || IS_STR(c)) {
                    char *arg1 = TO_STR(b);
                    char *arg2 = TO_STR(c);

                    char *arg3 = malloc((strlen(arg1) + strlen(arg2) + 1) + sizeof *arg3);

                    strcpy(arg3, arg1);
                    strcat(arg3, arg2);

                    registers[a].value.o = make_string_ref(vm, arg3);
                    registers[a].type = OBJECT_REFERENCE; // put this after

                    free(arg1);
                    free(arg2);
                } else {
                    if (!(IS_INT(b) || IS_REAL(b)) || !(IS_INT(c) || IS_REAL(c))) {
                        fatal("Cannot add types.");
                    }

                    if (IS_INT(b) && IS_INT(c)) {
                        int arg1 = AS_INT(b);
                        int arg2 = AS_INT(c);

                        registers[a].type = OBJECT_INT;
                        registers[a].value.i = arg1 + arg2;
                    } else {
                        double arg1 = IS_INT(b) ? (double) AS_INT(b) : AS_REAL(b);
                        double arg2 = IS_INT(c) ? (double) AS_INT(c) : AS_REAL(c);

                        registers[a].type = OBJECT_REAL;
                        registers[a].value.d = arg1 + arg2;
                    }
                }
            } break;

            case OP_SUB:
            {
                if (!(IS_INT(b) || IS_REAL(b)) || !(IS_INT(c) || IS_REAL(c))) {
                    fatal("Tried to sub non-numbers.");
                }

                if (IS_INT(b) && IS_INT(c)) {
                    int arg1 = AS_INT(b);
                    int arg2 = AS_INT(c);

                    registers[a].type = OBJECT_INT;
                    registers[a].value.i = arg1 - arg2;
                } else {
                    double arg1 = IS_INT(b) ? (double) AS_INT(b) : AS_REAL(b);
                    double arg2 = IS_INT(c) ? (double) AS_INT(c) : AS_REAL(c);

                    registers[a].type = OBJECT_REAL;
                    registers[a].value.d = arg1 - arg2;
                }
            } break;

            case OP_MUL:
            {
                if (!(IS_INT(b) || IS_REAL(b)) || !(IS_INT(c) || IS_REAL(c))) {
                    fatal("Tried to mul non-numbers.");
                }

                if (IS_INT(b) && IS_INT(c)) {
                    int arg1 = AS_INT(b);
                    int arg2 = AS_INT(c);

                    registers[a].type = OBJECT_INT;
                    registers[a].value.i = arg1 * arg2;
                } else {
                    double arg1 = IS_INT(b) ? (double) AS_INT(b) : AS_REAL(b);
                    double arg2 = IS_INT(c) ? (double) AS_INT(c) : AS_REAL(c);

                    registers[a].type = OBJECT_REAL;
                    registers[a].value.d = arg1 * arg2;
                }
            } break;

            case OP_DIV:
            {
                if (!(IS_INT(b) || IS_REAL(b)) || !(IS_INT(c) || IS_REAL(c))) {
                    fatal("Tried to div non-numbers.");
                }

                if ((IS_INT(c) && AS_INT(c) == 0) || (IS_REAL(c) && AS_REAL(c) == 0)) {
                    fatal("Div by 0.");
                }

                if (IS_INT(b) && IS_INT(c)) {
                    int arg1 = AS_INT(b);
                    int arg2 = AS_INT(c);

                    registers[a].type = OBJECT_INT;
                    registers[a].value.i = arg1 / arg2;
                } else {
                    double arg1 = IS_INT(b) ? (double) AS_INT(b) : AS_REAL(b);
                    double arg2 = IS_INT(c) ? (double) AS_INT(c) : AS_REAL(c);

                    registers[a].type = OBJECT_REAL;
                    registers[a].value.d = arg1 / arg2;
                }
            } break;

            case OP_MOD:
            {
                if (!(IS_INT(b) || IS_REAL(b)) || !(IS_INT(c) || IS_REAL(c))) {
                    fatal("Tried to div non-numbers.");
                }

                if ((IS_INT(c) && AS_INT(c) == 0) || (IS_REAL(c) && AS_REAL(c) == 0)) {
                    fatal("Mod by 0.");
                }

                if (IS_INT(b) && IS_INT(c)) {
                    int arg1 = AS_INT(b);
                    int arg2 = AS_INT(c);

                    registers[a].type = OBJECT_INT;
                    registers[a].value.i = arg1 % arg2;
                } else {
                    double arg1 = IS_INT(b) ? (double) AS_INT(b) : AS_REAL(b);
                    double arg2 = IS_INT(c) ? (double) AS_INT(c) : AS_REAL(c);

                    registers[a].type = OBJECT_REAL;
                    registers[a].value.i = fmod(arg1, arg2);
                }
            } break;

            case OP_POW:
            {
                if (!(IS_INT(b) || IS_REAL(b)) || !(IS_INT(c) || IS_REAL(c))) {
                    fatal("Tried to div non-numbers.");
                }

                if (IS_INT(b) && IS_INT(c)) {
                    int arg1 = AS_INT(b);
                    int arg2 = AS_INT(c);

                    registers[a].type = OBJECT_INT;
                    registers[a].value.i = (int) pow(arg1, arg2);
                } else {
                    double arg1 = IS_INT(b) ? (double) AS_INT(b) : AS_REAL(b);
                    double arg2 = IS_INT(c) ? (double) AS_INT(c) : AS_REAL(c);

                    registers[a].type = OBJECT_REAL;
                    registers[a].value.d = pow(arg1, arg2);
                }
            } break;

            case OP_NEG:
            {
                if (IS_INT(b)) {
                    registers[a].type = OBJECT_INT;
                    registers[a].value.i = -AS_INT(b);
                } else if (IS_REAL(b)) {
                    registers[a].type = OBJECT_INT;
                    registers[a].value.i = -AS_REAL(b);
                } else {
                    fatal("Tried to negate non-numeric type.");
                }
            } break;

            case OP_NOT:
            {
                if (registers[a].type != OBJECT_BOOL) {
                    fatal("Expected boolean type, not %d.", registers[a].type);
                }

                registers[a].value.i = registers[a].value.i == 1 ? 0 : 1;
            } break;

            case OP_EQ:
            {
                if ((IS_INT(b) || IS_REAL(b)) && (IS_INT(c) || IS_REAL(c))) {
                    double arg1 = IS_INT(b) ? (double) AS_INT(b) : AS_REAL(b);
                    double arg2 = IS_INT(c) ? (double) AS_INT(c) : AS_REAL(c);

                    registers[a].type = OBJECT_BOOL;
                    registers[a].value.i = arg1 == arg2;
                } else {
                    fatal("Comparison of reference types not yet supported.");
                }
            } break;

            case OP_LT:
            {
                if (!(IS_INT(b) || IS_REAL(b)) || !(IS_INT(c) || IS_REAL(c))) {
                    fatal("Tried to compare non-numbers.");
                }

                double arg1 = IS_INT(b) ? (double) AS_INT(b) : AS_REAL(b);
                double arg2 = IS_INT(c) ? (double) AS_INT(c) : AS_REAL(c);

                registers[a].type = OBJECT_BOOL;
                registers[a].value.i = arg1 < arg2;
            } break;

            case OP_LE:
            {
                if (!(IS_INT(b) || IS_REAL(b)) || !(IS_INT(c) || IS_REAL(c))) {
                    fatal("Tried to compare non-numbers.");
                }

                double arg1 = IS_INT(b) ? (double) AS_INT(b) : AS_REAL(b);
                double arg2 = IS_INT(c) ? (double) AS_INT(c) : AS_REAL(c);

                registers[a].type = OBJECT_BOOL;
                registers[a].value.i = arg1 <= arg2;
            } break;

            case OP_CLOSURE:
            {
                Closure *child = make_closure(chunk->children[b]);

                int i;
                for (i = 0; i < chunk->children[b]->numupvars; i++) {
                    int inst = chunk->instructions[++frame->pc];

                    OpCode oc = GET_O(inst);
                    int ac = GET_A(inst);
                    int bc = GET_B(inst);
                    int cc = GET_C(inst);

                    if (oc == OP_MOVE) {
                        // first upval for this variable
                        child->upvals[ac] = make_upval(vm, bc);
                    } else {
                        // share upval
                        child->upvals[ac] = closure->upvals[bc];
                        child->upvals[ac]->refcount++;
                    }
                }

                registers[a].value.o = make_closure_ref(vm, child);
                registers[a].type = OBJECT_REFERENCE; // put this after
            } break;

            case OP_CALL:
            {
                if (registers[b].type != OBJECT_REFERENCE || registers[b].value.o->type != OBJECT_CLOSURE) {
                    fatal("Tried to call non-closure.");
                }

                // TODO - safety issue (see compile.c for notes)

                Closure *child = registers[b].value.o->value.c;
                Frame *subframe = make_frame(frame, child);

                int i;
                for (i = 0; i < child->chunk->numparams; i++) {
                    copy_object(&subframe->registers[i + 1], &registers[c + i]);
                }

                vm->current = subframe;
                goto restart;
            } break;

            case OP_RETURN:
            {
                UpvalNode *head;
                for (head = vm->open; head != NULL; ) {
                    Upval *u = head->upval;

                    if (u->data.ref.frame == frame) {
                        StackObject *o = malloc(sizeof *o);

                        if (!o) {
                            fatal("Out of memory.");
                        }

                        u->open = 0;
                        copy_object(o, &registers[u->data.ref.slot]);
                        u->data.o = o;

                        if (vm->open == head) {
                            vm->open = head->next;
                        } else {
                            head->next->prev = head->prev;
                            head->prev->next = head->next;
                        }

                        UpvalNode *temp = head;
                        head = head->next;
                        free(temp);
                    } else {
                        head = head->next;
                    }
                }

                if (vm->current->parent != NULL) {
                    Frame *p = vm->current->parent;
                    StackObject *target = &p->registers[GET_A(p->closure->chunk->instructions[p->pc++])];

                    if (b < 256) {
                        // debug
                        char *d = obj_to_str(&registers[b]);
                        printf("Return value: %s\n", d);
                        free(d);

                        copy_object(target, &registers[b]);
                    } else {
                        copy_constant(vm, target, chunk->constants[b - 256]);
                    }

                    free_frame(frame);

                    vm->current = p;
                    goto restart;
                } else {
                    // debug
                    char *d = obj_to_str(&registers[b]);
                    printf("Return value: %s\n", d);
                    free(d);

                    free_frame(frame);
                    vm->current = NULL;
                    return;
                }
            } break;

            case OP_JUMP:
                frame->pc += c ? -b : b;
                break;

            case OP_JUMP_TRUE:
            {
                if (registers[a].type != OBJECT_BOOL) {
                    fatal("Expected boolean type, not %d.", registers[a].type);
                }

                if (registers[a].value.i == 1) {
                    frame->pc += c ? -b : b;
                }
            } break;

            case OP_JUMP_FALSE:
            {
                if (registers[a].type != OBJECT_BOOL) {
                    fatal("Expected boolean type, not %d.", registers[a].type);
                }

                if (registers[a].value.i == 0) {
                    frame->pc += c ? -b : b;
                }
            } break;

            case OP_ENTER_TRY:
            {
                vm->catchframe = make_catch_frame(frame, vm->catchframe, frame->pc + b);
            } break;

            case OP_LEAVE_TRY:
            {
                CatchFrame *temp = vm->catchframe;
                vm->catchframe = vm->catchframe->parent;
                free_catch_frame(temp);
            } break;

            case OP_THROW:
            {
                // TODO - replace unwinding of stack with an exceptions
                // table per-chunk. It will have an instructions range,
                // the starting instruction of a handler, and the type of
                // exception that it may handle.

                // Exception table:
                // From    To      Target      Type
                // 0       4       5           Class TestExc1
                // 0       12      12          Class TestExc2

                // TODO - implement a way to expect an exception
                // of a given type instead of a generic catch-all.

                char *s = obj_to_str(&registers[a]);
                printf("Exception value: %s!\n", s);
                free(s);

                // TODO - this is probably wrong. Not sure how complicated
                // it will be to handle upvalues and frame destruction here,
                // so we're just doing it a shitty way for now :D [GO LAZE].

                if (!vm->catchframe) {
                    // TODO - print a stack trace [ requires debug symbols :( ]
                    fatal("Exception thrown outside of handler.");
                }

                while (vm->current != vm->catchframe->frame) {
                    // TODO - destruct frame
                    vm->current = vm->current->parent;
                }

                vm->current->pc = vm->catchframe->target;

                CatchFrame *temp = vm->catchframe;
                vm->catchframe = vm->catchframe->parent;
                free_catch_frame(temp);

                goto restart;
            } break;
        }

        frame->pc++;
    }

    fatal("VM left instruction-space.");
}
}
Beispiel #18
0
static PyObject *
GMPy_Real_Mod(PyObject *x, PyObject *y, CTXT_Object *context)
{
    MPFR_Object *tempx = NULL, *tempy = NULL, *temp, *result;

    CHECK_CONTEXT(context);

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

    if (IS_REAL(x) && IS_REAL(y)) {
        tempx = GMPy_MPFR_From_Real(x, 1, context);
        tempy = GMPy_MPFR_From_Real(y, 1, context);
        if (!tempx || !tempy) {
            SYSTEM_ERROR("could not convert Real to mpfr");
            goto error;
        }
        if (mpfr_zero_p(tempy->f)) {
            context->ctx.divzero = 1;
            if (context->ctx.traps & TRAP_DIVZERO) {
                GMPY_DIVZERO("mod() modulo by zero");
                goto error;
            }
        }

        if (mpfr_nan_p(tempx->f) || mpfr_nan_p(tempy->f) || mpfr_inf_p(tempx->f)) {
            context->ctx.invalid = 1;
            if (context->ctx.traps & TRAP_INVALID) {
                GMPY_INVALID("mod() invalid operation");
                goto error;
            }
            else {
                mpfr_set_nan(result->f);
            }
        }
        else if (mpfr_inf_p(tempy->f)) {
            context->ctx.invalid = 1;
            if (context->ctx.traps & TRAP_INVALID) {
                GMPY_INVALID("mod() invalid operation");
                goto error;
            }
            if (mpfr_signbit(tempy->f)) {
                mpfr_set_inf(result->f, -1);
            }
            else {
                result->rc = mpfr_set(result->f, tempx->f,
                                      GET_MPFR_ROUND(context));
            }
        }
        else {
            mpfr_fmod(result->f, tempx->f, tempy->f, GET_MPFR_ROUND(context));

            if (!mpfr_zero_p(result->f)) {
                if ((mpfr_sgn(tempy->f) < 0) != (mpfr_sgn(result->f) < 0)) {
                    mpfr_add(result->f, result->f, tempy->f, GET_MPFR_ROUND(context));
                }
            }
            else {
                mpfr_copysign(result->f, result->f, tempy->f, GET_MPFR_ROUND(context));
            }

            Py_DECREF((PyObject*)temp);
        }
        GMPY_MPFR_CHECK_RANGE(result, context);
        GMPY_MPFR_SUBNORMALIZE(result, context);

        Py_DECREF((PyObject*)tempx);
        Py_DECREF((PyObject*)tempy);
        return (PyObject*)result;
    }

    Py_DECREF((PyObject*)temp);
    Py_DECREF((PyObject*)result);
    Py_RETURN_NOTIMPLEMENTED;

  error:
    Py_XDECREF((PyObject*)tempx);
    Py_XDECREF((PyObject*)tempy);
    Py_DECREF((PyObject*)temp);
    Py_DECREF((PyObject*)result);
    return NULL;
}
Beispiel #19
0
static PyObject *
GMPy_MPQ_Factory(PyObject *self, PyObject *args, PyObject *keywds)
{
    MPQ_Object *result, *temp;
    PyObject *n, *m;
    int base = 10;
    Py_ssize_t argc, keywdc = 0;
    static char *kwlist[] = {"s", "base", NULL };
    CTXT_Object *context = NULL;

    if (self && CTXT_Check(self)) {
        context = (CTXT_Object*)self;
    }
    else {
        CHECK_CONTEXT(context);
    }

    argc = PyTuple_Size(args);
    if (keywds) {
        keywdc = PyDict_Size(keywds);
    }

    if (argc + keywdc > 2) {
        TYPE_ERROR("mpq() takes at most 2 arguments");
        return NULL;
    }

    if (argc + keywdc == 0) {
        if ((result = GMPy_MPQ_New(context))) {
            mpq_set_ui(result->q, 0, 1);
        }
        return (PyObject*)result;
    }

    if (argc == 0) {
        TYPE_ERROR("mpq() requires at least one non-keyword argument");
        return NULL;
    }

    n = PyTuple_GetItem(args, 0);

    /* Handle the case where the first argument is a string. */
    if (PyStrOrUnicode_Check(n)) {
        /* keyword base is legal */
        if (keywdc || argc > 1) {
            if (!(PyArg_ParseTupleAndKeywords(args, keywds, "O|i", kwlist, &n, &base))) {
                return NULL;
            }
        }

        if ((base != 0) && ((base < 2) || (base > 62))) {
            VALUE_ERROR("base for mpq() must be 0 or in the interval [2, 62]");
            return NULL;
        }

        return (PyObject*)GMPy_MPQ_From_PyStr(n, base, context);
    }

    /* Handle 1 argument. It must be non-complex number. */
    if (argc == 1) {
        if (IS_REAL(n)) {
            return (PyObject*)GMPy_MPQ_From_Number(n, context);
        }
    }

    /* Handle 2 arguments. Both arguments must be integer or rational. */
    if (argc == 2) {
        m = PyTuple_GetItem(args, 1);

        if (IS_RATIONAL(n) && IS_RATIONAL(m)) {
           result = GMPy_MPQ_From_Rational(n, context);
           temp = GMPy_MPQ_From_Rational(m, context);
           if (!result || !temp) {
               Py_XDECREF((PyObject*)result);
               Py_XDECREF((PyObject*)temp);
               return NULL;
            }

            if (mpq_sgn(temp->q) == 0) {
                ZERO_ERROR("zero denominator in mpq()");
                Py_DECREF((PyObject*)result);
                Py_DECREF((PyObject*)temp);
                return NULL;
            }

            mpq_div(result->q, result->q, temp->q);
            Py_DECREF((PyObject*)temp);
            return (PyObject*)result;
        }
    }

    TYPE_ERROR("mpq() requires numeric or string argument");
    return NULL;
}
Beispiel #20
0
static float pid_curve_value(const pid_curve_scaler *scaler)
{
    float y = y_on_curve(scaler->x, scaler->points, sizeof(scaler->points) / sizeof(scaler->points[0]));

    return 1.0f + (IS_REAL(y) ? y : 0.0f);
}
Beispiel #21
0
static PyObject *
GMPy_Real_Mul(PyObject *x, PyObject *y, CTXT_Object *context)
{
    MPFR_Object *result = NULL;

    CHECK_CONTEXT(context);

    if (!(result = GMPy_MPFR_New(0, context))) {
        /* LCOV_EXCL_START */
        return NULL;
        /* LCOV_EXCL_STOP */
    }

    if (MPFR_Check(x) && MPFR_Check(y)) {
        mpfr_clear_flags();
        result->rc = mpfr_mul(result->f, MPFR(x), MPFR(y), GET_MPFR_ROUND(context));
        goto done;
    }

    if (MPFR_Check(x)) {
        if (PyIntOrLong_Check(y)) {
            int error;
            long temp = GMPy_Integer_AsLongAndError(y, &error);

            if (!error) {
                mpfr_clear_flags();
                result->rc = mpfr_mul_si(result->f, MPFR(x), temp, GET_MPFR_ROUND(context));
                goto done;
            }
            else {
                mpz_t tempz;
                mpz_inoc(tempz);
                mpz_set_PyIntOrLong(tempz, y);
                mpfr_clear_flags();
                result->rc = mpfr_mul_z(result->f, MPFR(x), tempz, GET_MPFR_ROUND(context));
                mpz_cloc(tempz);
                goto done;
            }
        }

        if (CHECK_MPZANY(y)) {
            mpfr_clear_flags();
            result->rc = mpfr_mul_z(result->f, MPFR(x), MPZ(y), GET_MPFR_ROUND(context));
            goto done;
        }

        if (IS_RATIONAL(y)) {
            MPQ_Object *tempy = NULL;

            if (!(tempy = GMPy_MPQ_From_Number(y, context))) {
                /* LCOV_EXCL_START */
                Py_DECREF((PyObject*)result);
                return NULL;
                /* LCOV_EXCL_STOP */
            }

            mpfr_clear_flags();
            result->rc = mpfr_mul_q(result->f, MPFR(x), tempy->q, GET_MPFR_ROUND(context));
            Py_DECREF((PyObject*)tempy);
            goto done;
        }

        if (PyFloat_Check(y)) {
            mpfr_clear_flags();
            result->rc = mpfr_mul_d(result->f, MPFR(x), PyFloat_AS_DOUBLE(y), GET_MPFR_ROUND(context));
            goto done;
        }
    }

    if (MPFR_Check(y)) {
        if (PyIntOrLong_Check(x)) {
            int error;
            long temp = GMPy_Integer_AsLongAndError(x, &error);

            if (!error) {
                mpfr_clear_flags();
                result->rc = mpfr_mul_si(result->f, MPFR(y), temp, GET_MPFR_ROUND(context));
                goto done;
            }
            else {
                mpz_t tempz;
                mpz_inoc(tempz);
                mpz_set_PyIntOrLong(tempz, x);
                mpfr_clear_flags();
                result->rc = mpfr_mul_z(result->f, MPFR(y), tempz, GET_MPFR_ROUND(context));
                mpz_cloc(tempz);
                goto done;
            }
        }

        if (CHECK_MPZANY(x)) {
            mpfr_clear_flags();
            result->rc = mpfr_mul_z(result->f, MPFR(y), MPZ(x), GET_MPFR_ROUND(context));
            goto done;
        }

        if (IS_RATIONAL(x)) {
            MPQ_Object *tempx = NULL;

            if (!(tempx = GMPy_MPQ_From_Number(x, context))) {
                /* LCOV_EXCL_START */
                Py_DECREF((PyObject*)result);
                return NULL;
                /* LCOV_EXCL_STOP */
            }

            mpfr_clear_flags();
            result->rc = mpfr_mul_q(result->f, MPFR(y), tempx->q, GET_MPFR_ROUND(context));
            Py_DECREF((PyObject*)tempx);
            goto done;
        }

        if (PyFloat_Check(x)) {
            mpfr_clear_flags();
            result->rc = mpfr_mul_d(result->f, MPFR(y), PyFloat_AS_DOUBLE(x), GET_MPFR_ROUND(context));
            goto done;
        }
    }

    if (IS_REAL(x) && IS_REAL(y)) {
        MPFR_Object *tempx = NULL, *tempy = NULL;

        if (!(tempx = GMPy_MPFR_From_Real(x, 1, context)) ||
            !(tempy = GMPy_MPFR_From_Real(y, 1, context))) {
            /* LCOV_EXCL_START */
            Py_XDECREF((PyObject*)tempx);
            Py_XDECREF((PyObject*)tempy);
            Py_DECREF((PyObject*)result);
            return NULL;
            /* LCOV_EXCL_STOP */
        }

        mpfr_clear_flags();
        result->rc = mpfr_mul(result->f, MPFR(tempx), MPFR(tempy), GET_MPFR_ROUND(context));
        Py_DECREF((PyObject*)tempx);
        Py_DECREF((PyObject*)tempy);
        goto done;
    }

    /* LCOV_EXCL_START */
    Py_DECREF((PyObject*)result);
    SYSTEM_ERROR("Internal error in GMPy_Real_Mul().");
    return NULL;
    /* LCOV_EXCL_STOP */

  done:
    _GMPy_MPFR_Cleanup(&result, context);
    return (PyObject*)result;
}
Beispiel #22
0
static PyObject *
GMPy_Real_Sub(PyObject *x, PyObject *y, CTXT_Object *context)
{
    MPFR_Object *result;

    CHECK_CONTEXT(context);

    if (!(result = GMPy_MPFR_New(0, context)))
        return NULL;

    /* This only processes mpfr if the exponent is still in-bounds. Need
     * to handle the rare case at the end. */

    if (MPFR_Check(x) && MPFR_Check(y)) {
        mpfr_clear_flags();
        result->rc = mpfr_sub(result->f, MPFR(x), MPFR(y), GET_MPFR_ROUND(context));
        goto done;
    }

    if (MPFR_Check(x)) {
        if (PyIntOrLong_Check(y)) {
            int error;
            long temp = GMPy_Integer_AsLongAndError(y, &error);
            if (!error) {
                mpfr_clear_flags();
                result->rc = mpfr_sub_si(result->f, MPFR(x), temp, GET_MPFR_ROUND(context));
                goto done;
            }
            else {
                mpz_t tempz;
                mpz_inoc(tempz);
                mpz_set_PyIntOrLong(tempz, y);
                mpfr_clear_flags();
                result->rc = mpfr_sub_z(result->f, MPFR(x), tempz, GET_MPFR_ROUND(context));
                mpz_cloc(tempz);
                goto done;
            }
        }

        if (CHECK_MPZANY(y)) {
            mpfr_clear_flags();
            result->rc = mpfr_sub_z(result->f, MPFR(x), MPZ(y), GET_MPFR_ROUND(context));
            goto done;
        }

        if (IS_RATIONAL(y)) {
            MPQ_Object *tempy;

            if (!(tempy = GMPy_MPQ_From_Number(y, context))) {
                Py_DECREF((PyObject*)result);
                return NULL;
            }
            mpfr_clear_flags();
            result->rc = mpfr_sub_q(result->f, MPFR(x), tempy->q, GET_MPFR_ROUND(context));
            Py_DECREF((PyObject*)tempy);
            goto done;
        }

        if (PyFloat_Check(y)) {
            mpfr_clear_flags();
            result->rc = mpfr_sub_d(result->f, MPFR(x), PyFloat_AS_DOUBLE(y), GET_MPFR_ROUND(context));
            goto done;
        }
    }

    if (MPFR_Check(y)) {
        if (PyIntOrLong_Check(x)) {
            int error;
            long temp = GMPy_Integer_AsLongAndError(x, &error);
            if (!error) {
                mpfr_clear_flags();
                result->rc = mpfr_sub_si(result->f, MPFR(y), temp, GET_MPFR_ROUND(context));
                mpfr_neg(result->f, result->f, GET_MPFR_ROUND(context));
                goto done;
            }
            else {
                mpz_t tempz;
                mpz_inoc(tempz);
                mpz_set_PyIntOrLong(tempz, x);
                mpfr_clear_flags();
                result->rc = mpfr_sub_z(result->f, MPFR(y), tempz, GET_MPFR_ROUND(context));
                mpfr_neg(result->f, result->f, GET_MPFR_ROUND(context));
                mpz_cloc(tempz);
                goto done;
            }
        }

        if (CHECK_MPZANY(x)) {
            mpfr_clear_flags();
            result->rc = mpfr_sub_z(result->f, MPFR(y), MPZ(x), GET_MPFR_ROUND(context));
            mpfr_neg(result->f, result->f, GET_MPFR_ROUND(context));
            goto done;
        }

        if (IS_RATIONAL(x)) {
            MPQ_Object *tempx;

            if (!(tempx = GMPy_MPQ_From_Number(x, context))) {
                Py_DECREF((PyObject*)result);
                return NULL;
            }
            mpfr_clear_flags();
            result->rc = mpfr_sub_q(result->f, MPFR(y), tempx->q, GET_MPFR_ROUND(context));
            mpfr_neg(result->f, result->f, GET_MPFR_ROUND(context));
            Py_DECREF((PyObject*)tempx);
            goto done;
        }

        if (PyFloat_Check(x)) {
            mpfr_clear_flags();
            result->rc = mpfr_sub_d(result->f, MPFR(y), PyFloat_AS_DOUBLE(x), GET_MPFR_ROUND(context));
            mpfr_neg(result->f, result->f, GET_MPFR_ROUND(context));
            goto done;
        }
    }

    if (IS_REAL(x) && IS_REAL(y)) {
        MPFR_Object *tempx, *tempy;

        tempx = GMPy_MPFR_From_Real(x, 1, context);
        tempy = GMPy_MPFR_From_Real(y, 1, context);
        if (!tempx || !tempy) {
            Py_XDECREF((PyObject*)tempx);
            Py_XDECREF((PyObject*)tempy);
            Py_DECREF((PyObject*)result);
            return NULL;
        }
        mpfr_clear_flags();
        result->rc = mpfr_sub(result->f, MPFR(tempx), MPFR(tempy), GET_MPFR_ROUND(context));
        Py_DECREF((PyObject*)tempx);
        Py_DECREF((PyObject*)tempy);
        goto done;
    }

    Py_DECREF((PyObject*)result);
    Py_RETURN_NOTIMPLEMENTED;

  done:
    GMPY_MPFR_CLEANUP(result, context, "subtraction");
    return (PyObject*)result;
}
Beispiel #23
0
static PyObject *
GMPy_Real_DivMod_2(PyObject *x, PyObject *y, CTXT_Object *context)
{
    MPFR_Object *tempx = NULL, *tempy = NULL, *quo = NULL, *rem = NULL;
    PyObject *result = NULL;

    CHECK_CONTEXT(context);

    if (!(result = PyTuple_New(2)) ||
        !(rem = GMPy_MPFR_New(0, context)) ||
        !(quo = GMPy_MPFR_New(0, context))) {

        /* LCOV_EXCL_START */
        goto error;
        /* LCOV_EXCL_STOP */
    }

    if (IS_REAL(x) && IS_REAL(y)) {
        if (!(tempx = GMPy_MPFR_From_Real(x, 1, context)) ||
            !(tempy = GMPy_MPFR_From_Real(y, 1, context))) {

            /* LCOV_EXCL_START */
            goto error;
            /* LCOV_EXCL_STOP */
        }

        if (mpfr_zero_p(tempy->f)) {
            context->ctx.divzero = 1;
            if (context->ctx.traps & TRAP_DIVZERO) {
                GMPY_DIVZERO("divmod() division by zero");
                goto error;
            }
        }

        if (mpfr_nan_p(tempx->f) || mpfr_nan_p(tempy->f) || mpfr_inf_p(tempx->f)) {
            context->ctx.invalid = 1;
            if (context->ctx.traps & TRAP_INVALID) {
                GMPY_INVALID("divmod() invalid operation");
                goto error;
            }
            else {
                mpfr_set_nan(quo->f);
                mpfr_set_nan(rem->f);
            }
        }
        else if (mpfr_inf_p(tempy->f)) {
            context->ctx.invalid = 1;
            if (context->ctx.traps & TRAP_INVALID) {
                GMPY_INVALID("divmod() invalid operation");
                goto error;
            }
            if (mpfr_zero_p(tempx->f)) {
                mpfr_set_zero(quo->f, mpfr_sgn(tempy->f));
                mpfr_set_zero(rem->f, mpfr_sgn(tempy->f));
            }
            else if ((mpfr_signbit(tempx->f)) != (mpfr_signbit(tempy->f))) {
                mpfr_set_si(quo->f, -1, MPFR_RNDN);
                mpfr_set_inf(rem->f, mpfr_sgn(tempy->f));
            }
            else {
                mpfr_set_si(quo->f, 0, MPFR_RNDN);
                rem->rc = mpfr_set(rem->f, tempx->f, MPFR_RNDN);
            }
        }
        else {
            MPQ_Object *mpqx = NULL, *mpqy = NULL, *temp_rem = NULL;
            MPZ_Object *temp_quo = NULL;

            if (!(mpqx = GMPy_MPQ_From_MPFR(tempx, context)) ||
                !(mpqy = GMPy_MPQ_From_MPFR(tempy, context))) {

                /* LCOV_EXCL_START */
                Py_XDECREF((PyObject*)mpqx);
                Py_XDECREF((PyObject*)mpqy);
                goto error;
                /* LCOV_EXCL_STOP */
            }

            if (!(temp_rem = GMPy_MPQ_New(context)) ||
                !(temp_quo = GMPy_MPZ_New(context))) {

                /* LCOV_EXCL_START */
                Py_XDECREF((PyObject*)temp_rem);
                Py_XDECREF((PyObject*)temp_quo);
                Py_XDECREF((PyObject*)mpqx);
                Py_XDECREF((PyObject*)mpqy);
                goto error;
                /* LCOV_EXCL_STOP */
            }

            Py_DECREF((PyObject*)tempx);
            Py_DECREF((PyObject*)tempy);

            mpq_div(temp_rem->q, mpqx->q, mpqy->q);
            mpz_fdiv_q(temp_quo->z, mpq_numref(temp_rem->q), mpq_denref(temp_rem->q));
            /* Need to calculate x - quo * y. */
            mpq_set_z(temp_rem->q, temp_quo->z);
            mpq_mul(temp_rem->q, temp_rem->q, mpqy->q);
            mpq_sub(temp_rem->q, mpqx->q, temp_rem->q);

            Py_DECREF((PyObject*)mpqx);
            Py_DECREF((PyObject*)mpqy);

            quo->rc = mpfr_set_z(quo->f, temp_quo->z, MPFR_RNDD);
            rem->rc = mpfr_set_q(rem->f, temp_rem->q, MPFR_RNDN);

            Py_DECREF((PyObject*)temp_rem);
            Py_DECREF((PyObject*)temp_quo);

            GMPY_MPFR_CHECK_RANGE(quo, context);
            GMPY_MPFR_CHECK_RANGE(rem, context);
            GMPY_MPFR_SUBNORMALIZE(quo, context);
            GMPY_MPFR_SUBNORMALIZE(rem, context);

            PyTuple_SET_ITEM(result, 0, (PyObject*)quo);
            PyTuple_SET_ITEM(result, 1, (PyObject*)rem);
            return result;
        }
    }

    /* LCOV_EXCL_START */
    SYSTEM_ERROR("Internal error in GMPy_Real_DivMod_2().");
  error:
    Py_XDECREF((PyObject*)tempx);
    Py_XDECREF((PyObject*)tempy);
    Py_XDECREF((PyObject*)rem);
    Py_XDECREF((PyObject*)quo);
    Py_XDECREF(result);
    return NULL;
    /* LCOV_EXCL_STOP */
}
Beispiel #24
0
static PyObject *
GMPy_Real_DivMod_1(PyObject *x, PyObject *y, CTXT_Object *context)
{
    MPFR_Object *tempx = NULL, *tempy = NULL, *quo = NULL, *rem = NULL;
    PyObject *result = NULL;

    CHECK_CONTEXT(context);

    if (!(result = PyTuple_New(2)) ||
        !(rem = GMPy_MPFR_New(0, context)) ||
        !(quo = GMPy_MPFR_New(0, context))) {

        /* LCOV_EXCL_START */
        goto error;
        /* LCOV_EXCL_STOP */
    }

    if (IS_REAL(x) && IS_REAL(y)) {

        if (!(tempx = GMPy_MPFR_From_Real(x, 1, context)) ||
            !(tempy = GMPy_MPFR_From_Real(y, 1, context))) {

            /* LCOV_EXCL_START */
            goto error;
            /* LCOV_EXCL_STOP */
        }
        if (mpfr_zero_p(tempy->f)) {
            context->ctx.divzero = 1;
            if (context->ctx.traps & TRAP_DIVZERO) {
                GMPY_DIVZERO("divmod() division by zero");
                goto error;
            }
        }

        if (mpfr_nan_p(tempx->f) || mpfr_nan_p(tempy->f) || mpfr_inf_p(tempx->f)) {
            context->ctx.invalid = 1;
            if (context->ctx.traps & TRAP_INVALID) {
                GMPY_INVALID("divmod() invalid operation");
                goto error;
            }
            else {
                mpfr_set_nan(quo->f);
                mpfr_set_nan(rem->f);
            }
        }
        else if (mpfr_inf_p(tempy->f)) {
            context->ctx.invalid = 1;
            if (context->ctx.traps & TRAP_INVALID) {
                GMPY_INVALID("divmod() invalid operation");
                goto error;
            }
            if (mpfr_zero_p(tempx->f)) {
                mpfr_set_zero(quo->f, mpfr_sgn(tempy->f));
                mpfr_set_zero(rem->f, mpfr_sgn(tempy->f));
            }
            else if ((mpfr_signbit(tempx->f)) != (mpfr_signbit(tempy->f))) {
                mpfr_set_si(quo->f, -1, MPFR_RNDN);
                mpfr_set_inf(rem->f, mpfr_sgn(tempy->f));
            }
            else {
                mpfr_set_si(quo->f, 0, MPFR_RNDN);
                rem->rc = mpfr_set(rem->f, tempx->f, MPFR_RNDN);
            }
        }
        else {
            MPFR_Object *temp;

            if (!(temp = GMPy_MPFR_New(0, context))) {
                /* LCOV_EXCL_START */
                goto error;
                /* LCOV_EXCL_STOP */
            }
            mpfr_fmod(rem->f, tempx->f, tempy->f, MPFR_RNDN);
            mpfr_sub(temp->f, tempx->f, rem->f, MPFR_RNDN);
            mpfr_div(quo->f, temp->f, tempy->f, MPFR_RNDN);

            if (!mpfr_zero_p(rem->f)) {
                if ((mpfr_sgn(tempy->f) < 0) != (mpfr_sgn(rem->f) < 0)) {
                    mpfr_add(rem->f, rem->f, tempy->f, MPFR_RNDN);
                    mpfr_sub_ui(quo->f, quo->f, 1, MPFR_RNDN);
                }
            }
            else {
                mpfr_copysign(rem->f, rem->f, tempy->f, MPFR_RNDN);
            }

            if (!mpfr_zero_p(quo->f)) {
                mpfr_round(quo->f, quo->f);
            }
            else {
                mpfr_setsign(quo->f, quo->f, mpfr_sgn(tempx->f) * mpfr_sgn(tempy->f) - 1, MPFR_RNDN);
            }
            Py_DECREF((PyObject*)temp);
        }

        GMPY_MPFR_CHECK_RANGE(quo, context);
        GMPY_MPFR_CHECK_RANGE(rem, context);
        GMPY_MPFR_SUBNORMALIZE(quo, context);
        GMPY_MPFR_SUBNORMALIZE(rem, context);

        Py_DECREF((PyObject*)tempx);
        Py_DECREF((PyObject*)tempy);
        PyTuple_SET_ITEM(result, 0, (PyObject*)quo);
        PyTuple_SET_ITEM(result, 1, (PyObject*)rem);
        return (PyObject*)result;
    }

    /* LCOV_EXCL_START */
    SYSTEM_ERROR("Internal error in GMPy_Real_DivMod_1().");
  error:
    Py_XDECREF((PyObject*)tempx);
    Py_XDECREF((PyObject*)tempy);
    Py_XDECREF((PyObject*)rem);
    Py_XDECREF((PyObject*)quo);
    Py_XDECREF(result);
    return NULL;
    /* LCOV_EXCL_STOP */
}
Beispiel #25
0
static PyObject *
GMPy_Real_Add(PyObject *x, PyObject *y, CTXT_Object *context)
{
    MPFR_Object *result;

    CHECK_CONTEXT(context);

    if (!(result = GMPy_MPFR_New(0, context)))
        return NULL;

    if (MPFR_Check(x) && MPFR_Check(y)) {
        mpfr_clear_flags();
        result->rc = mpfr_add(result->f, MPFR(x), MPFR(y), GET_MPFR_ROUND(context));
        goto done;
    }

    if (MPFR_Check(x)) {
        if (PyIntOrLong_Check(y)) {
            mpz_t tempz;
            long temp;
            int error;

            temp = GMPy_Integer_AsLongAndError(y, &error);
            
            if (error) {
                mpz_inoc(tempz);
                mpz_set_PyIntOrLong(tempz, y);
                mpfr_clear_flags();
                result->rc = mpfr_add_z(result->f, MPFR(x), tempz, GET_MPFR_ROUND(context));
                mpz_cloc(tempz);
                goto done;
            }
            else {
                mpfr_clear_flags();
                result->rc = mpfr_add_si(result->f, MPFR(x), temp, GET_MPFR_ROUND(context));
                goto done;
            }
        }

        if (CHECK_MPZANY(y)) {
            mpfr_clear_flags();
            result->rc = mpfr_add_z(result->f, MPFR(x), MPZ(y), GET_MPFR_ROUND(context));
            goto done;
        }

        if (IS_RATIONAL(y)) {
            MPQ_Object *tempy;

            if (!(tempy = GMPy_MPQ_From_Number(y, context))) {
                Py_DECREF((PyObject*)result);
                return NULL;
            }
            mpfr_clear_flags();
            result->rc = mpfr_add_q(result->f, MPFR(x), tempy->q, GET_MPFR_ROUND(context));
            Py_DECREF((PyObject*)tempy);
            goto done;
        }

        if (PyFloat_Check(y)) {
            mpfr_clear_flags();
            result->rc = mpfr_add_d(result->f, MPFR(x), PyFloat_AS_DOUBLE(y), GET_MPFR_ROUND(context));
            goto done;
        }
    }

    if (MPFR_Check(y)) {
        if (PyIntOrLong_Check(x)) {
            mpz_t tempz;
            long temp;
            int error;

            temp = GMPy_Integer_AsLongAndError(x, &error);
            if (error) {
                mpz_inoc(tempz);
                mpz_set_PyIntOrLong(tempz, x);
                mpfr_clear_flags();
                result->rc = mpfr_add_z(result->f, MPFR(y), tempz, GET_MPFR_ROUND(context));
                mpz_cloc(tempz);
                goto done;
            }
            else {
                mpfr_clear_flags();
                result->rc = mpfr_add_si(result->f, MPFR(y), temp, GET_MPFR_ROUND(context));
                goto done;
            }
        }

        if (CHECK_MPZANY(x)) {
            mpfr_clear_flags();
            result->rc = mpfr_add_z(result->f, MPFR(y), MPZ(x), GET_MPFR_ROUND(context));
            goto done;
        }

        if (IS_RATIONAL(x)) {
            MPQ_Object *tempx;

            if (!(tempx = GMPy_MPQ_From_Number(x, context))) {
                Py_DECREF((PyObject*)result);
                return NULL;
            }
            mpfr_clear_flags();
            result->rc = mpfr_add_q(result->f, MPFR(y), tempx->q, GET_MPFR_ROUND(context));
            Py_DECREF((PyObject*)tempx);
            goto done;
        }

        if (PyFloat_Check(x)) {
            mpfr_clear_flags();
            result->rc = mpfr_add_d(result->f, MPFR(y), PyFloat_AS_DOUBLE(x), GET_MPFR_ROUND(context));
            goto done;
        }
    }

    if (IS_REAL(x) && IS_REAL(y)) {
        MPFR_Object *tempx, *tempy;

        tempx = GMPy_MPFR_From_Real(x, 1, context);
        tempy = GMPy_MPFR_From_Real(y, 1, context);
        if (!tempx || !tempy) {
            Py_XDECREF((PyObject*)tempx);
            Py_XDECREF((PyObject*)tempy);
            Py_DECREF((PyObject*)result);
            return NULL;
        }
        mpfr_clear_flags();
        result->rc = mpfr_add(result->f, MPFR(tempx), MPFR(tempy), GET_MPFR_ROUND(context));
        Py_DECREF((PyObject*)tempx);
        Py_DECREF((PyObject*)tempy);
        goto done;
    }

    Py_DECREF((PyObject*)result);
    Py_RETURN_NOTIMPLEMENTED;

  done:
    GMPY_MPFR_CLEANUP(result, context, "addition");
    return (PyObject*)result;
}
Beispiel #26
0
static PyObject *
GMPy_Real_FloorDiv(PyObject *x, PyObject *y, CTXT_Object *context)
{
    MPFR_Object *result;

    CHECK_CONTEXT(context);

    if (!(result = GMPy_MPFR_New(0, context))) {
        /* LCOV_EXCL_START */
        return NULL;
        /* LCOV_EXCL_STOP */
    }

    if (MPFR_Check(x)) {
        if (MPFR_Check(y)) {
            mpfr_clear_flags();

            result->rc = mpfr_div(result->f, MPFR(x), MPFR(y), GET_MPFR_ROUND(context));
            result->rc = mpfr_floor(result->f, result->f);
            goto done;
        }

        if (PyIntOrLong_Check(y)) {
            int error;
            long tempi = GMPy_Integer_AsLongAndError(y, &error);

            if (!error) {
                mpfr_clear_flags();

                result->rc = mpfr_div_si(result->f, MPFR(x), tempi, GET_MPFR_ROUND(context));
                result->rc = mpfr_floor(result->f, result->f);
                goto done;
            }
            else {
                mpz_set_PyIntOrLong(global.tempz, y);
                mpfr_clear_flags();

                result->rc = mpfr_div_z(result->f, MPFR(x), global.tempz, GET_MPFR_ROUND(context));
                result->rc = mpfr_floor(result->f, result->f);
                goto done;
            }
        }

        if (CHECK_MPZANY(y)) {
            mpfr_clear_flags();

            result->rc = mpfr_div_z(result->f, MPFR(x), MPZ(y), GET_MPFR_ROUND(context));
            result->rc = mpfr_floor(result->f, result->f);
            goto done;
        }

        if (IS_RATIONAL(y)) {
            MPQ_Object *tempy;

            if (!(tempy = GMPy_MPQ_From_Number(y, context))) {
                Py_DECREF((PyObject*)result);
                return NULL;
            }
            mpfr_clear_flags();

            result->rc = mpfr_div_q(result->f, MPFR(x), tempy->q, GET_MPFR_ROUND(context));
            result->rc = mpfr_floor(result->f, result->f);
            Py_DECREF((PyObject*)tempy);
            goto done;
        }

        if (PyFloat_Check(y)) {
            mpfr_clear_flags();

            result->rc = mpfr_div_d(result->f, MPFR(x), PyFloat_AS_DOUBLE(y), GET_MPFR_ROUND(context));
            result->rc = mpfr_floor(result->f, result->f);
            goto done;
        }
    }

    if (MPFR_Check(y)) {
        if (PyIntOrLong_Check(x)) {
            int error;
            long tempi = GMPy_Integer_AsLongAndError(x, &error);
            if (!error) {
                mpfr_clear_flags();

                result->rc = mpfr_si_div(result->f, tempi, MPFR(y), GET_MPFR_ROUND(context));
                result->rc = mpfr_floor(result->f, result->f);
                goto done;
            }
        }

        /* Since mpfr_z_div does not exist, this combination is handled at the
         * end by converting x to an mpfr. Ditto for rational.*/

        if (PyFloat_Check(x)) {
            mpfr_clear_flags();

            result->rc = mpfr_d_div(result->f, PyFloat_AS_DOUBLE(x), MPFR(y), GET_MPFR_ROUND(context));
            result->rc = mpfr_floor(result->f, result->f);
            goto done;
        }
    }

    /* Handle the remaining cases.
     * Note: verify that MPZ if converted at full precision! */

    if (IS_REAL(x) && IS_REAL(y)) {
        MPFR_Object *tempx, *tempy;

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

        result->rc = mpfr_div(result->f, MPFR(tempx), MPFR(tempy), GET_MPFR_ROUND(context));
        result->rc = mpfr_floor(result->f, result->f);
        Py_DECREF((PyObject*)tempx);
        Py_DECREF((PyObject*)tempy);
        goto done;
    }

    Py_DECREF((PyObject*)result);
    Py_RETURN_NOTIMPLEMENTED;

  done:
    _GMPy_MPFR_Cleanup(&result, context);
    return (PyObject*)result;
}
Beispiel #27
0
static PyObject *
GMPy_Complex_Pow(PyObject *base, PyObject *exp, PyObject *mod, CTXT_Object *context)
{
    MPC_Object *tempb = NULL, *tempe = NULL, *result= NULL;
    MPFR_Object *tempf = NULL;
    MPZ_Object *tempz = NULL;

    if (mod != Py_None) {
        TYPE_ERROR("pow() 3rd argument not allowed unless all arguments are integers");
        return NULL;
    }

    CHECK_CONTEXT(context);

    result = GMPy_MPC_New(0, 0, context);
    tempb = GMPy_MPC_From_Complex(base, 1, 1, context);
    if (!result || !tempb) {
        goto err;
    }

    mpfr_clear_flags();

    if (PyIntOrLong_Check(exp)) {
        int error;
        long temp_exp = GMPy_Integer_AsLongAndError(exp, &error);
        
        if (!error) {
            result->rc = mpc_pow_si(result->c, tempb->c, temp_exp, GET_MPC_ROUND(context));
        }
        else {
            mpz_t tempzz;
            mpz_inoc(tempzz);
            mpz_set_PyIntOrLong(tempzz, exp);
            result->rc = mpc_pow_z(result->c, tempb->c, tempzz, GET_MPC_ROUND(context));
            mpz_cloc(tempzz);
        }
    }
    else if (IS_INTEGER(exp)) {
        if (!(tempz = GMPy_MPZ_From_Integer(exp, context))) {
            goto err;
        }
        result->rc = mpc_pow_z(result->c, tempb->c, tempz->z, GET_MPC_ROUND(context));
    }
    else if (IS_REAL(exp)) {
        if (!(tempf = GMPy_MPFR_From_Real(exp, 1, context))) {
            goto err;
        }
        result->rc = mpc_pow_fr(result->c, tempb->c, tempf->f, GET_MPC_ROUND(context));
    }
    else {
        if (!(tempe = GMPy_MPC_From_Complex(exp, 1, 1, context))) {
            goto err;
        }
        result->rc = mpc_pow(result->c, tempb->c, tempe->c, GET_MPC_ROUND(context));
    }

    GMPY_MPC_CLEANUP(result, context, "pow()");
    Py_XDECREF((PyObject*)tempz);
    Py_XDECREF((PyObject*)tempf);
    Py_XDECREF((PyObject*)tempe);
    Py_XDECREF((PyObject*)tempb);
    return (PyObject*)result;

  err:
    Py_XDECREF((PyObject*)result);
    Py_XDECREF((PyObject*)tempz);
    Py_XDECREF((PyObject*)tempf);
    Py_XDECREF((PyObject*)tempe);
    Py_XDECREF((PyObject*)tempb);
    return NULL;
}
Beispiel #28
0
static Data_Obj *insure_ram_obj(QSP_ARG_DECL  Data_Obj *dp)
{
	Data_Obj *tmp_dp;
	char *tname;
	Data_Area *save_ap;
	Data_Obj *c_dp=NULL;

	if( OBJ_IS_RAM(dp) ) return dp;

	// This object lives on a different platform.
	// We create a copy in RAM, and download the data
	// using the platform download function.

	save_ap = curr_ap;
	curr_ap = ram_area_p;

	tname = getbuf( strlen(OBJ_NAME(dp)) + strlen(DNAME_PREFIX) + 1 );
	sprintf(tname,"%s%s",DNAME_PREFIX,OBJ_NAME(dp));
	tmp_dp = dup_obj(QSP_ARG  dp, tname);
	givbuf(tname);
	if( tmp_dp == NO_OBJ ){
		// This can happen if the object is subscripted,
		// as the bracket characters are illegal in names
		return NO_OBJ;
	}

	curr_ap = save_ap;

	// We can't download if the source data is not contiguous...
	//
	// We have a problem with bit precision, because the bits can
	// be non-contiguous when the long words are - any time the number of columns
	// is not evenly divided by the bits-per-word

	if( (! IS_CONTIGUOUS(dp)) && ! HAS_CONTIGUOUS_DATA(dp) ){
		Vec_Obj_Args oa1, *oap=&oa1;

advise("object is not contiguous, and does not have contiguous data...");
longlist(QSP_ARG  dp);
		save_ap = curr_ap;
		curr_ap = OBJ_AREA( dp );

		tname = getbuf( strlen(OBJ_NAME(dp)) + strlen(CNAME_PREFIX) + 1 );
		sprintf(tname,"%s%s",CNAME_PREFIX,OBJ_NAME(dp));
		c_dp = dup_obj(QSP_ARG  dp, tname );
		givbuf(tname);

		curr_ap = save_ap;

		// Now do the move...

		setvarg2(oap,c_dp,dp);
		if( IS_BITMAP(dp) ){
			SET_OA_SBM(oap,dp);
			SET_OA_SRC1(oap,NO_OBJ);
		}

		if( IS_REAL(dp) ) /* BUG case for QUAT too? */
			OA_ARGSTYPE(oap) = REAL_ARGS;
		else if( IS_COMPLEX(dp) ) /* BUG case for QUAT too? */
			OA_ARGSTYPE(oap) = COMPLEX_ARGS;
		else if( IS_QUAT(dp) ) /* BUG case for QUAT too? */
			OA_ARGSTYPE(oap) = QUATERNION_ARGS;
		else
			//ERROR1("CAUTIOUS:  insure_ram_obj:  bad argset type!?");
			assert( AERROR("insure_ram_obj:  bad argset type!?") );

//fprintf(stderr,"insure_ram_obj:  moving remote data to a contiguous object\n");  
		call_vfunc( QSP_ARG  FIND_VEC_FUNC(FVMOV), oap );
//fprintf(stderr,"insure_ram_obj:  DONE moving remote data to a contiguous object\n");  

		dp = c_dp;
	}

	gen_obj_dnload(QSP_ARG  tmp_dp, dp);

	if( c_dp != NO_OBJ )
		delvec(QSP_ARG  c_dp);

	// BUG - when to delete?
	// We try using the VOLATILE flag.  This will work as long as
	// the input object is not VOLATILE!?

	SET_OBJ_FLAG_BITS(tmp_dp, DT_VOLATILE ) ;

	return tmp_dp;
}