예제 #1
0
box2f SphericalDeformation::deformedToLocalBounds(const vec3d &deformedCenter, double deformedRadius) const
{
    vec3d p = deformedToLocal(deformedCenter);
    double r = deformedRadius;

    if (isInf(p.x) || isInf(p.y)) {
        return box2f();
    }

    double k = (1.0 - r * r / (2.0 * R * R)) * vec3d(p.x, p.y, R).length();
    double A = k * k - p.x * p.x;
    double B = k * k - p.y * p.y;
    double C = -2.0 * p.x * p.y;
    double D = -2.0 * R * R * p.x;
    double E = -2.0 * R * R * p.y;
    double F = R * R * (k * k - R * R);

    double a = C * C - 4.0 * A * B;
    double b = 2.0 * C * E - 4.0 * B * D;
    double c = E * E - 4.0 * B * F;
    double d = sqrt(b * b - 4.0 * a * c);
    double x1 = (- b - d) / (2.0 * a);
    double x2 = (- b + d) / (2.0 * a);

    b = 2.0 * C * D - 4.0 * A * E;
    c = D * D - 4.0 * A * F;
    d = sqrt(b * b - 4.0 * a * c);
    double y1 = (- b - d) / (2.0 * a);
    double y2 = (- b + d) / (2.0 * a);

    return box2f(vec2f(x1, y1), vec2f(x2, y2));
}
예제 #2
0
//-----------------------------------------------------------------------------
double APowerPack::getBatteryLevel() const
{
  if ( isInf(mBatteryCapacity) )
    return 1.0;

  return mBatteryCapacity / mMaxBatteryCapacity;
}
예제 #3
0
파일: array.cpp 프로젝트: zmanchun/insieme
	ArrayType::ArrayType(const NodePtr& node) {
		assert_true(node) << "Given node is null!";

		// support expressions as input
		auto type = node.isa<GenericTypePtr>();
		if (auto expr = node.isa<ExpressionPtr>()) type = expr->getType().isa<GenericTypePtr>();

		// check given node type
		assert_true(isArrayType(type)) << "Given node " << *node << " is not a array type!";

		// process node type
		if(isInf(type->getTypeParameter(1))) {
			// unknown sized array
			*this = ArrayType(type->getTypeParameter(0), ExpressionPtr());
		} else if (auto num = type->getTypeParameter(1).isa<NumericTypePtr>()) {
			// variable or fixed sized array
			*this = ArrayType(type->getTypeParameter(0), num->getValue());
		} else {
			// check validity
			auto size = type->getTypeParameter(1).isa<TypeVariablePtr>();
			assert_true(size) << "Invalid size parameter: " << *size << " of kind: " << size->getNodeType();
			// generic array type
			*this = ArrayType(type->getTypeParameter(0), size);
		}
	}
예제 #4
0
int DecimalUtil::quantum(Decimal64 x)
{
    BSLS_ASSERT(!isInf(x));
    BSLS_ASSERT(!isNan(x));

    return decDoubleGetExponent(x.data());
}
예제 #5
0
int DecimalUtil::quantum(Decimal128 x)
{
    BSLS_ASSERT(!isInf(x));
    BSLS_ASSERT(!isNan(x));

    return decQuadGetExponent(x.data());
}
예제 #6
0
파일: router1.c 프로젝트: zinjiggle/router
bool broadCastLinkInfo(int messagetype, struct LINK link, struct NetworkTopoStruct* Topo)
{
	char buf[MAXDATASIZE];
	int length = 0;
	int i;
	length = 1+sizeof(struct LINK);
	buf[0] = (char)messagetype;
	memcpy(&buf[1],&link, sizeof(struct LINK));
	buf[length] = '\0';
	char broadresult[MAXDATASIZE];
	char temp[MAXDATASIZE];
	memset(broadresult,'\0',MAXDATASIZE);
	
	for(i=0;i<Topo->neighNum;i++)
	{
		if(isInf(Topo->Neighs[i].cost)) continue; // do not broadcast link info through links with infinite cost
		if(isNodeInLink(Topo->Neighs[i].addr,link)) continue; // do not broadcast link info to nodes the nodes in the link
		else{
			if(udpTalkTo(Topo->Neighs[i].host,Topo->Neighs[i].udpport,buf,length) != 0)
    			{
    				perror("ERR broadCastLinkInfo: udp talking error.");
    				exit(1);
    			}
    			else
    			{
    				sprintf(temp,"%d ", Topo->Neighs[i].addr);
    				strcat(broadresult,temp);
    			}
		}
	}
	if(strlen(broadresult)>0)
		printf("%d broadCastLinkInfo: %d <%d %d %.0f> through Neighs: %s\n",Topo->myaddr,messagetype,link.nodeAddr[0],link.nodeAddr[1],link.cost,broadresult);
	return 1;
}
예제 #7
0
bool EXParser::evaluateFunction(std::string &_expression, const int index, EXFunctionSet::iterator fiter)

{

	std::string paramExpression = isolateParenthesisExpression(_expression, index);

	size_t expressionLen = paramExpression.length();

	if(expressionLen == 0){
	  mErrorStr = "function parameter error";
	  return false;
	}

	if(!priorityLoop(paramExpression))
	  return false;

	double value = fiter->second((double)atof(paramExpression.c_str()));

	if(isInf(value)){
	  mErrorStr = "infinity error";
	  return false;
	}

	if(isNan(value)){
	  mErrorStr = "not a number error";
	  return false;
	}

	steps.push_back(EXSolveStep(fiter->first+"("+paramExpression+") -> "+dblToStr(value), ""));

	_expression.replace(index-fiter->first.length(), fiter->first.length()+expressionLen+2, dblToStr(value));


	return true;
}
예제 #8
0
bool AbsScarRegionDetector::is_valid(float * val){
	for(int i=0; i < this->dim; i++){
		if(isNaN(val[i]) || isInf(val[i]) || isNegInf(val[i])) 
			return false;
	}
	return true;
}
예제 #9
0
파일: float.c 프로젝트: Ahmah2009/golang
bool
runtime·isNaN(float64 f)
{
	uint64 x;

	x = runtime·float64tobits(f);
	return ((uint32)(x>>52) & 0x7FF) == 0x7FF && !runtime·isInf(f, 0);
}
예제 #10
0
파일: internal.cpp 프로젝트: KDE/kjs
double roundValue(double d)
{
    double ad = fabs(d);
    if (ad == 0 || isNaN(d) || isInf(d)) {
        return d;
    }
    return copysign(floor(ad), d);
}
예제 #11
0
파일: internal.cpp 프로젝트: KDE/kjs
int32_t toInt32(double d, bool &ok)
{
    ok = true;
    if (isNaN(d) || isInf(d)) {
        ok = false;
        return 0;
    }
    return toInt32(d);
}
예제 #12
0
파일: math.c 프로젝트: aryx/fork-kencc
double
errcheck(double d, char* s)	/* check result of library call */
{
	if(isNaN(d))
		execerror(s, "argument out of domain");
	if(isInf(d, 0))
		execerror(s, "result out of range");
	return d;
}
예제 #13
0
파일: nan.c 프로젝트: AustenConrad/plan-9
int
isNaN(double d)
{
	FPdbleword a;

	a.x = d;
	if((a.hi & NANMASK) != NANEXP)
		return 0;
	return !isInf(d, 0);
}
예제 #14
0
파일: QPCommon.cpp 프로젝트: hpropp/drake
void addJointSoftLimits(const JointSoftLimitParams &params, const DrakeRobotState &robot_state, const VectorXd &q_des, std::vector<SupportStateElement,Eigen::aligned_allocator<SupportStateElement>> &supports, std::vector<drake::lcmt_joint_pd_override> &joint_pd_override) {
  Matrix<bool, Dynamic, 1> has_joint_override = Matrix<bool, Dynamic, 1>::Zero(q_des.size());
  for (std::vector<drake::lcmt_joint_pd_override>::iterator it = joint_pd_override.begin(); it != joint_pd_override.end(); ++it) {
    has_joint_override(it->position_ind - 1) = true;
  }
  for (int i=0; i < params.lb.size(); i++) {
    if (!has_joint_override(i) && params.enabled(i)) {
      int disable_body_1idx = params.disable_when_body_in_support(i);
      if (disable_body_1idx == 0 || !inSupport(supports, disable_body_1idx - 1)) {
        double w_lb = 0;
        double w_ub = 0;
        if (!isInf(params.lb(i))) {
          w_lb = logisticSigmoid(params.weight(i), params.k_logistic(i), params.lb(i), robot_state.q(i));
        }
        if (!isInf(params.ub(i))) {
          w_ub = logisticSigmoid(params.weight(i), params.k_logistic(i), robot_state.q(i), params.ub(i));
        }
        double weight = std::max(w_ub, w_lb);
        drake::lcmt_joint_pd_override override;
        override.position_ind = i + 1;
        override.qi_des = q_des(i);
예제 #15
0
파일: internal.cpp 프로젝트: KDE/kjs
uint16_t toUInt16(double dd)
{
    double d = roundValue(dd);
    if (isNaN(d) || isInf(d)) {
        return 0;
    }
    double d16 = fmod(d, D16);

    if (d16 < 0) {
        d16 += D16;
    }

    return static_cast<uint16_t>(d16);
}
예제 #16
0
파일: internal.cpp 프로젝트: KDE/kjs
uint32_t toUInt32(double dd)
{
    double d = roundValue(dd);
    if (isNaN(d) || isInf(d)) {
        return 0;
    }
    double d32 = fmod(d, D32);

    if (d32 < 0) {
        d32 += D32;
    }

    return static_cast<uint32_t>(d32);
}
예제 #17
0
파일: nan.c 프로젝트: UIKit0/newsqueak
int
isNaN(double d)
{
	union
	{
		double	d;
		long	x[2];
	} a;

	a.d = d;
	if((a.x[1] & NANMASK) != NANEXP)
		return 0;
	return !isInf(d, 0);
}
예제 #18
0
파일: internal.cpp 프로젝트: KDE/kjs
int32_t toInt32(double d)
{
    if (isNaN(d) || isInf(d)) {
        return 0;
    }
    double d32 = fmod(roundValue(d), D32);

    if (d32 >= D32 / 2) {
        d32 -= D32;
    } else if (d32 < -D32 / 2) {
        d32 += D32;
    }

    return static_cast<int32_t>(d32);
}
예제 #19
0
파일: value.cpp 프로젝트: vasi/kdelibs
uint32_t JSValue::toUInt32SlowCase(double d, bool& ok)
{
    ok = true;

    if (d >= 0.0 && d < D32)
        return static_cast<uint32_t>(d);

    if (isNaN(d) || isInf(d)) {
        ok = false;
        return 0;
    }

    double d32 = fmod(trunc(d), D32);
    if (d32 < 0)
        d32 += D32;
    return static_cast<uint32_t>(d32);
}
예제 #20
0
파일: array.cpp 프로젝트: zmanchun/insieme
	bool ArrayType::isArrayType(const NodePtr& node) {
		auto type = node.isa<GenericTypePtr>();
		if(!type) return false;

		// simple approach: use unification
		NodeManager& mgr = node.getNodeManager();
		const ArrayExtension& ext = mgr.getLangExtension<ArrayExtension>();

		// unify given type with template type
		auto ref = ext.getGenArray().as<GenericTypePtr>();
		auto sub = types::match(mgr, type, ref);
		if(!sub) return false;

		// check instantiation
		const types::Substitution& map = *sub;
		auto size = map.applyTo(ref->getTypeParameter(1));
		return size.isa<TypeVariablePtr>() || size.isa<NumericTypePtr>() || isInf(size);
	}
예제 #21
0
파일: sqrt.c 프로젝트: aahud/harvey
/*
	sqrtC returns the square root of its floating
	point argument. Newton's method.

	calls frexp
*/
double
sqrtC(double arg)
{
	double x, temp;
	int exp, i;

	if(arg <= 0) {
		if(arg < 0)
			return NaN();
		return 0;
	}
	if(isInf(arg, 1))
		return arg;
	x = frexp(arg, &exp);
	while(x < 0.5) {
		x *= 2;
		exp--;
	}
	/*
	 * NOTE
	 * this wont work on 1's comp
	 */
	if(exp & 1) {
		x *= 2;
		exp--;
	}
	temp = 0.5 * (1.0+x);

	while(exp > 60) {
		temp *= (1L<<30);
		exp -= 60;
	}
	while(exp < -60) {
		temp /= (1L<<30);
		exp += 60;
	}
	if(exp >= 0)
		temp *= 1L << (exp/2);
	else
		temp /= 1L << (-exp/2);
	for(i=0; i<=4; i++)
		temp = 0.5*(temp + arg/temp);
	return temp;
}
예제 #22
0
파일: value.cpp 프로젝트: vasi/kdelibs
int32_t JSValue::toInt32SlowCase(double d, bool& ok)
{
    ok = true;

    if (d >= -D32 / 2 && d < D32 / 2)
        return static_cast<int32_t>(d);

    if (isNaN(d) || isInf(d)) {
        ok = false;
        return 0;
    }

    double d32 = fmod(trunc(d), D32);
    if (d32 >= D32 / 2)
        d32 -= D32;
    else if (d32 < -D32 / 2)
        d32 += D32;
    return static_cast<int32_t>(d32);
}
예제 #23
0
파일: EXParser.cpp 프로젝트: sukovanej/qum
void EXParser::evaluateFunction(std::string &_expression, const int index, EXFunctionSet::iterator fiter)
{
	std::string paramExpression = isolateParenthesisExpression(_expression, index);
	size_t expressionLen = paramExpression.length();
	if(expressionLen == 0){
		throw EXError("function_parameter_error", ErrorIndex::FUNCTION_PARAMETER_ERROR);
	}
	priorityLoop(paramExpression);
	double value = fiter->second((double)atof(paramExpression.c_str()));
	if(isInf(value)){
		throw EXError("infinity_error", ErrorIndex::INFINITY_ERROR);
	}
	if(isNan(value)){
		throw EXError("not_a_number", ErrorIndex::NAN_ERROR);
	}
	steps.push_back(EXSolveStep(fiter->first+"("+paramExpression+") -> "+dblToStr(value), ""));
	_expression.replace(index-fiter->first.length(), fiter->first.length()+expressionLen+2, dblToStr(value));

}
예제 #24
0
STD1::uint32_t Document::writeNameMap( std::FILE* out )
{
    STD1::uint32_t offset( 0 );
    if( !isInf() && !nameMap.empty() ) {
        offset = std::ftell( out );
        ConstNameMapIter itr;
        for( itr = nameMap.begin(); itr != nameMap.end(); ++itr ) {
            STD1::uint16_t index( itr->first->index() );
            if( std::fwrite( &index, sizeof( STD1::uint16_t ), 1, out ) != 1 )
                throw FatalError( ERR_WRITE );
        }
        for( itr = nameMap.begin(); itr != nameMap.end(); ++itr ) {
            STD1::uint16_t idx( itr->second.index() );
            if( std::fwrite( &idx, sizeof( STD1::uint16_t ), 1, out ) != 1 )
                throw FatalError( ERR_WRITE );
        }
    }
    return offset;
}
예제 #25
0
// Write the file
void Document::write( std::FILE *out )
{
    hdr->write( out );   //write the header
    hdr->panelCount = static_cast< STD1::uint16_t>( resMap.size() );
    hdr->panelOffset = writeResMap( out );
    hdr->nameCount = !isInf() ? static_cast< STD1::uint16_t >( nameMap.size() ) : 0;
    hdr->nameOffset = writeNameMap( out );
    eHdr->gNameOffset = gnames->write( out );
    eHdr->gNameCount = gnames->size();
    hdr->imageOffset = writeBitmaps( out );
    hdr->tocCount = static_cast< STD1::uint16_t >( pages.size() );
    hdr->tocOffset = writeTOCs( out );
    hdr->tocOffsetOffset = writeTOCOffsets( out );
    writeSynonyms( out );
    hdr->indexOffset = writeIndex( out );
    hdr->icmdOffset = writeICmd( out );
    hdr->nlsOffset = nls->write( out );
    hdr->nlsSize = nls->length();
    eHdr->stringsOffset = strings->write( out );
    eHdr->stringsSize = static_cast< STD1::uint16_t >( strings->length() );
    eHdr->dbOffset = extfiles->write( out );
    eHdr->dbCount = static_cast< STD1::uint16_t >( extfiles->size() );
    eHdr->dbSize = extfiles->length();
    eHdr->fontOffset = fonts->write( out );
    eHdr->fontCount = static_cast< STD1::uint16_t >( fonts->size() );
    eHdr->ctrlOffset = controls->write( out );
    eHdr->ctrlSize = controls->length();
    hdr->dictOffset = dict->write( out );
    hdr->dictSize = dict->length();
    hdr->dictCount = dict->size();
    writeCells( out );
    hdr->cellCount = static_cast< STD1::uint16_t >( cells.size() );
    hdr->cellOffsetOffset = writeCellOffsets( out );
    eHdr->childPagesOffset = writeChildWindows( out );
    if( compiler.searchable() ) {
        hdr->searchOffset = dict->writeFTS( out, hdr->recSize );
        hdr->searchSize = dict->ftsLength();
    }
    hdr->extOffset = eHdr->write( out );
    hdr->write( out );   //rewrite the header to update the offsets
}
예제 #26
0
파일: EXParser.cpp 프로젝트: sukovanej/qum
void EXParser::evaluateOperator(std::string & _expression, const int index, EXOperatorSet::iterator oiter)
{
	if(oiter->first!='('){
		std::string leftVal, rightVal, strVal;
		if((leftVal = getLeftOfOperator(_expression, index-1)).empty() || (rightVal = getRightOfOperator(_expression, index+1)).empty()){
			throw EXError("operator_logic_error", ErrorIndex::OPERATOR_LOGIC_ERROR);
		}

		double value = oiter->second(strToDbl(leftVal.c_str()), strToDbl(rightVal.c_str()));
		if(isInf(value)){
			throw EXError("infinity_error", ErrorIndex::INFINITY_ERROR);
		}
		if(isNan(value)){
			throw EXError("not_a_number", ErrorIndex::NAN_ERROR);
		}
		_expression.replace(index-leftVal.length(), leftVal.length() + rightVal.length()+1, dblToStr(value));
	}
	else{
		evaluateParenthesis(_expression, index);
	}
}
예제 #27
0
bool EXParser::evaluateOperator(std::string & _expression, const int index, EXOperatorSet::iterator oiter)

{

	if(oiter->first!='('){

		std::string leftVal, rightVal, strVal;

		if((leftVal = getLeftOfOperator(_expression, index-1)).empty() || (rightVal = getRightOfOperator(_expression, index+1)).empty()){

		  mErrorStr = "operator logic error";
		  return false;
		}



		double value = oiter->second(strToDbl(leftVal.c_str()), strToDbl(rightVal.c_str()));

		if(isInf(value)){
		  mErrorStr = "infinity error";
		  return false;
		}

		if(isNan(value)){
		  mErrorStr = "not a number";
		  return false;
		}

		_expression.replace(index-leftVal.length(), leftVal.length() + rightVal.length()+1, dblToStr(value));

	}

	else{

		evaluateParenthesis(_expression, index);

	}

	return true;
}
예제 #28
0
파일: fltfmt.c 프로젝트: 8l/inferno
static void
xdtoa(Fmt *fmt, char *s2, double f)
{
	char s1[NSIGNIF+10];
	double g, h;
	int e, d, i, n;
	int c1, c2, c3, c4, ucase, sign, chr, prec;

	prec = FDEFLT;
	if(fmt->flags & FmtPrec)
		prec = fmt->prec;
	if(prec > FDIGIT)
		prec = FDIGIT;
	if(isNaN(f)) {
		strcpy(s2, "NaN");
		return;
	}
	if(isInf(f, 1)) {
		strcpy(s2, "+Inf");
		return;
	}
	if(isInf(f, -1)) {
		strcpy(s2, "-Inf");
		return;
	}
	sign = 0;
	if(f < 0) {
		f = -f;
		sign++;
	}
	ucase = 0;
	chr = fmt->r;
	if(isupper(chr)) {
		ucase = 1;
		chr = tolower(chr);
	}

	e = 0;
	g = f;
	if(g != 0) {
		frexp(f, &e);
		e = e * .301029995664;
		if(e >= -150 && e <= +150) {
			d = 0;
			h = f;
		} else {
			d = e/2;
			h = f * pow10(-d);
		}
		g = h * pow10(d-e);
		while(g < 1) {
			e--;
			g = h * pow10(d-e);
		}
		while(g >= 10) {
			e++;
			g = h * pow10(d-e);
		}
	}

	/*
	 * convert NSIGNIF digits and convert
	 * back to get accuracy.
	 */
	for(i=0; i<NSIGNIF; i++) {
		d = g;
		s1[i] = d + '0';
		g = (g - d) * 10;
	}
	s1[i] = 0;

	/*
	 * try decimal rounding to eliminate 9s
	 */
	c2 = prec + 1;
	if(chr == 'f')
		c2 += e;
	if(c2 >= NSIGNIF-2) {
		strcpy(s2, s1);
		d = e;
		s1[NSIGNIF-2] = '0';
		s1[NSIGNIF-1] = '0';
		sprint(s1+NSIGNIF, "e%d", e-NSIGNIF+1);
		g = strtod(s1, nil);
		if(g == f)
			goto found;
		if(xadd(s1, NSIGNIF-3, 1)) {
			e++;
			sprint(s1+NSIGNIF, "e%d", e-NSIGNIF+1);
		}
		g = strtod(s1, nil);
		if(g == f)
			goto found;
		strcpy(s1, s2);
		e = d;
	}

	/*
	 * convert back so s1 gets exact answer
	 */
	for(;;) {
		sprint(s1+NSIGNIF, "e%d", e-NSIGNIF+1);
		g = strtod(s1, nil);
		if(f > g) {
			if(xadd(s1, NSIGNIF-1, 1))
				e--;
			continue;
		}
		if(f < g) {
			if(xsub(s1, NSIGNIF-1, 1))
				e++;
			continue;
		}
		break;
	}

found:
	/*
	 * sign
	 */
	d = 0;
	i = 0;
	if(sign)
		s2[d++] = '-';
	else if(fmt->flags & FmtSign)
		s2[d++] = '+';
	else if(fmt->flags & FmtSpace)
		s2[d++] = ' ';

	/*
	 * copy into final place
	 * c1 digits of leading '0'
	 * c2 digits from conversion
	 * c3 digits of trailing '0'
	 * c4 digits after '.'
	 */
	c1 = 0;
	c2 = prec + 1;
	c3 = 0;
	c4 = prec;
	switch(chr) {
	default:
		if(xadd(s1, c2, 5))
			e++;
		break;
	case 'g':
		/*
		 * decide on 'e' of 'f' style convers
		 */
		if(xadd(s1, c2, 5))
			e++;
		if(e >= -5 && e <= prec) {
			c1 = -e - 1;
			c4 = prec - e;
			chr = 'h';	// flag for 'f' style
		}
		break;
	case 'f':
		if(xadd(s1, c2+e, 5))
			e++;
		c1 = -e;
		if(c1 > prec)
			c1 = c2;
		c2 += e;
		break;
	}

	/*
	 * clean up c1 c2 and c3
	 */
	if(c1 < 0)
		c1 = 0;
	if(c2 < 0)
		c2 = 0;
	if(c2 > NSIGNIF) {
		c3 = c2-NSIGNIF;
		c2 = NSIGNIF;
	}

	/*
	 * copy digits
	 */
	while(c1 > 0) {
		if(c1+c2+c3 == c4)
			s2[d++] = '.';
		s2[d++] = '0';
		c1--;
	}
	while(c2 > 0) {
		if(c2+c3 == c4)
			s2[d++] = '.';
		s2[d++] = s1[i++];
		c2--;
	}
	while(c3 > 0) {
		if(c3 == c4)
			s2[d++] = '.';
		s2[d++] = '0';
		c3--;
	}

	/*
	 * strip trailing '0' on g conv
	 */
	if(fmt->flags & FmtSharp) {
		if(0 == c4)
			s2[d++] = '.';
	} else
	if(chr == 'g' || chr == 'h') {
		for(n=d-1; n>=0; n--)
			if(s2[n] != '0')
				break;
		for(i=n; i>=0; i--)
			if(s2[i] == '.') {
				d = n;
				if(i != n)
					d++;
				break;
			}
	}
	if(chr == 'e' || chr == 'g') {
		if(ucase)
			s2[d++] = 'E';
		else
			s2[d++] = 'e';
		c1 = e;
		if(c1 < 0) {
			s2[d++] = '-';
			c1 = -c1;
		} else
			s2[d++] = '+';
		if(c1 >= 100) {
			s2[d++] = c1/100 + '0';
			c1 = c1%100;
		}
		s2[d++] = c1/10 + '0';
		s2[d++] = c1%10 + '0';
	}
	s2[d] = 0;
}
예제 #29
0
파일: Constant.cpp 프로젝트: 3dcl/glslang
//
// Do single unary node folding
//
TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TType& returnType)
{
    TConstUnion *unionArray = getUnionArrayPointer();
    int objectSize = getType().getObjectSize();

    // First, size the result, which is mostly the same as the argument's size,
    // but not always.
    TConstUnion* newConstArray;
    switch (op) {
    // TODO: functionality: constant folding: finish listing exceptions to size here
    case EOpDeterminant:
    case EOpAny:
    case EOpAll:
    case EOpLength:
        newConstArray = new TConstUnion[1];
        break;

    case EOpEmitStreamVertex:
    case EOpEndStreamPrimitive:
        // These don't actually fold
        return 0;

    default:
        newConstArray = new TConstUnion[objectSize];
    }

    // Process non-component-wise operations
    switch (op) {
    case EOpLength:
    case EOpNormalize:
    {
        double sum = 0;
        for (int i = 0; i < objectSize; i++)
            sum += double(unionArray[i].getDConst()) * unionArray[i].getDConst();
        double length = sqrt(sum);
        if (op == EOpLength)
            newConstArray[0].setDConst(length);
        else {
            for (int i = 0; i < objectSize; i++)
                newConstArray[i].setDConst(unionArray[i].getDConst() / length);
        }
        break;
    }
    default:
        break;
    }

    for (int i = 0; i < objectSize; i++) {
        switch (op) {
        case EOpNegative:
            switch (getType().getBasicType()) {
            case EbtDouble:
            case EbtFloat: newConstArray[i].setDConst(-unionArray[i].getDConst()); break;
            case EbtInt:   newConstArray[i].setIConst(-unionArray[i].getIConst()); break;
            case EbtUint:  newConstArray[i].setUConst(static_cast<unsigned int>(-static_cast<int>(unionArray[i].getUConst())));  break;
            default:
                return 0;
            }
            break;
        case EOpLogicalNot:
        case EOpVectorLogicalNot:
            switch (getType().getBasicType()) {
            case EbtBool:  newConstArray[i].setBConst(!unionArray[i].getBConst()); break;
            default:
                return 0;
            }
            break;
        case EOpBitwiseNot:
            newConstArray[i] = ~unionArray[i];
            break;
        case EOpRadians:
            newConstArray[i].setDConst(unionArray[i].getDConst() * pi / 180.0);
            break;
        case EOpDegrees:
            newConstArray[i].setDConst(unionArray[i].getDConst() * 180.0 / pi);
            break;
        case EOpSin:
            newConstArray[i].setDConst(sin(unionArray[i].getDConst()));
            break;
        case EOpCos:
            newConstArray[i].setDConst(cos(unionArray[i].getDConst()));
            break;
        case EOpTan:
            newConstArray[i].setDConst(tan(unionArray[i].getDConst()));
            break;
        case EOpAsin:
            newConstArray[i].setDConst(asin(unionArray[i].getDConst()));
            break;
        case EOpAcos:
            newConstArray[i].setDConst(acos(unionArray[i].getDConst()));
            break;
        case EOpAtan:
            newConstArray[i].setDConst(atan(unionArray[i].getDConst()));
            break;

        case EOpLength:
        case EOpNormalize:
            // handled above as special case
            break;

        case EOpDPdx:
        case EOpDPdy:
        case EOpFwidth:
            // The derivatives are all mandated to create a constant 0.
            newConstArray[i].setDConst(0.0);
            break;

        case EOpExp:
            newConstArray[i].setDConst(exp(unionArray[i].getDConst()));
            break;
        case EOpLog:
            newConstArray[i].setDConst(log(unionArray[i].getDConst()));
            break;
        case EOpExp2:
            {
                const double inv_log2_e = 0.69314718055994530941723212145818;
                newConstArray[i].setDConst(exp(unionArray[i].getDConst() * inv_log2_e));
                break;
            }
        case EOpLog2:
            {
                const double log2_e = 1.4426950408889634073599246810019;
                newConstArray[i].setDConst(log2_e * log(unionArray[i].getDConst()));
                break;
            }
        case EOpSqrt:
            newConstArray[i].setDConst(sqrt(unionArray[i].getDConst()));
            break;
        case EOpInverseSqrt:
            newConstArray[i].setDConst(1.0 / sqrt(unionArray[i].getDConst()));
            break;

        case EOpAbs:
            if (unionArray[i].getType() == EbtDouble)
                newConstArray[i].setDConst(fabs(unionArray[i].getDConst()));
            else if (unionArray[i].getType() == EbtInt)
                newConstArray[i].setIConst(abs(unionArray[i].getIConst()));
            else
                newConstArray[i] = unionArray[i];
            break;
        case EOpSign:
            #define SIGN(X) (X == 0 ? 0 : (X < 0 ? -1 : 1))
            if (unionArray[i].getType() == EbtDouble)
                newConstArray[i].setDConst(SIGN(unionArray[i].getDConst()));
            else
                newConstArray[i].setIConst(SIGN(unionArray[i].getIConst()));
            break;
        case EOpFloor:
            newConstArray[i].setDConst(floor(unionArray[i].getDConst()));
            break;
        case EOpTrunc:
            if (unionArray[i].getDConst() > 0)
                newConstArray[i].setDConst(floor(unionArray[i].getDConst()));
            else
                newConstArray[i].setDConst(ceil(unionArray[i].getDConst()));
            break;
        case EOpRound:
            newConstArray[i].setDConst(floor(0.5 + unionArray[i].getDConst()));
            break;
        case EOpRoundEven:
        {
            double flr = floor(unionArray[i].getDConst());
            bool even = flr / 2.0 == floor(flr / 2.0);
            double rounded = even ? ceil(unionArray[i].getDConst() - 0.5) : floor(unionArray[i].getDConst() + 0.5);
            newConstArray[i].setDConst(rounded);
            break;
        }
        case EOpCeil:
            newConstArray[i].setDConst(ceil(unionArray[i].getDConst()));
            break;
        case EOpFract:
        {
            double x = unionArray[i].getDConst();
            newConstArray[i].setDConst(x - floor(x));
            break;
        }

        case EOpIsNan:
        {
            newConstArray[i].setBConst(isNan(unionArray[i].getDConst()));
            break;
        }
        case EOpIsInf:
        {
            newConstArray[i].setBConst(isInf(unionArray[i].getDConst()));
            break;
        }

        // TODO: Functionality: constant folding: the rest of the ops have to be fleshed out

        case EOpSinh:
        case EOpCosh:
        case EOpTanh:
        case EOpAsinh:
        case EOpAcosh:
        case EOpAtanh:

        case EOpFloatBitsToInt:
        case EOpFloatBitsToUint:
        case EOpIntBitsToFloat:
        case EOpUintBitsToFloat:

        case EOpPackSnorm2x16:
        case EOpUnpackSnorm2x16:
        case EOpPackUnorm2x16:
        case EOpUnpackUnorm2x16:
        case EOpPackHalf2x16:
        case EOpUnpackHalf2x16:

        case EOpDeterminant:
        case EOpMatrixInverse:
        case EOpTranspose:

        case EOpAny:
        case EOpAll:

        default:
            return 0;
        }
    }

    TIntermConstantUnion *newNode = new TIntermConstantUnion(newConstArray, returnType);
    newNode->getWritableType().getQualifier().storage = EvqConst;
    newNode->setLoc(getLoc());

    return newNode;
}
예제 #30
0
파일: Fund.cpp 프로젝트: Tythos/cuben
		bool isFin(float f) {
			return !isInf(f) && !isNan(f);
		}