int
saf_multiply_quantity(SAF_ParMode pmode,
SAF_Quantity *quantity, /* IN[OUT] The quantity which is affected by this operation */
SAF_Quantity *multiplier, /* What to multiply into QUANTITY */
int power /* Number of times to multiply MULTIPLIER into QUANTITY */
)
{
SAF_ENTER(saf_multiply_quantity, SAF_PRECONDITION_ERROR);
int i, recip;
unsigned dim_q=(SAF_DIMENSIONLESS_QUANTITY & SS_QUANTITY(quantity)->flags);
unsigned dim_m=(SAF_DIMENSIONLESS_QUANTITY & SS_QUANTITY(multiplier)->flags);
SAF_REQUIRE(_saf_valid_pmode(pmode), SAF_LOW_CHK_COST, SAF_PRECONDITION_ERROR,
_saf_errmsg("PMODE must be valid"));
if (!_saf_is_participating_proc(pmode)) SAF_RETURN(-1);
SAF_REQUIRE(SS_QUANTITY(quantity), SAF_LOW_CHK_COST, SAF_PRECONDITION_ERROR,
_saf_errmsg("QUANTITY must be a valid quantity handle"));
SAF_REQUIRE(SS_QUANTITY(multiplier), SAF_LOW_CHK_COST, SAF_PRECONDITION_ERROR,
_saf_errmsg("MULTIPLIER must be a valid quantity handle"));
/* Determine if Q is the reciprocal of M^POWER */
recip = (dim_q == dim_m);
for (i=0; i<SS_MAX_BASEQS && recip; i++)
if (SS_QUANTITY(quantity)->power[i] != -power*SS_QUANTITY(multiplier)->power[i]) recip=0;
SAF_DIRTY(quantity, pmode);
if (recip) {
/* If Q and M are reciprocals then turn U into a dimensionless quntity. */
SS_QUANTITY(quantity)->flags |= SAF_DIMENSIONLESS_QUANTITY;
} else if (dim_q==dim_m) {
/* If Q and M are both dimensioned quantities (the default) then multiply them in the normal cancelling fasion. If Q
* and M are both dimensionless quantities then they should have only positive powers and they can be added in the
* normal fasion (the powers refer to cancelling powers in the numerator and denominator). */
for (i=0; i<SS_MAX_BASEQS; i++)
SS_QUANTITY(quantity)->power[i] += power * SS_QUANTITY(multiplier)->power[i];
} else if (dim_q) {
/* If Q is dimensionless but M is dimensioned, then set Q to be M and turn off the dimensionless flag. In other words,
* the powers originally in Q cancel themselves. */
SS_QUANTITY(quantity)->flags &= ~SAF_DIMENSIONLESS_QUANTITY;
for (i=0; i<SS_MAX_BASEQS; i++)
SS_QUANTITY(quantity)->power[i] = power * SS_QUANTITY(multiplier)->power[i];
} else {
/* Q is dimensioned but M isn't. Just discard M since it would cancel itself anyway. */
}
SAF_LEAVE(SAF_SUCCESS);
}