c_exp c_exp::conversionTo(DataType outType) const { QString inCode = code(); DataType inType = type(); QString outCode; if (outType.isFloat()) { if (inType.isFloat()) { outCode = inCode; } else if (inType.isAFP()) { if (inType.afpPrecision() >= 0) { outCode = "(float)(" + inCode + ") / " + QString::number(1 << inType.afpPrecision()); } else { outCode = "(float)(" + inCode + ") * " + QString::number(1 << (-inType.afpPrecision())); } } else if (inType.isInt()) { outCode = "(float)(" + inCode + ")"; } else { outCode = inCode; // error condition } } else if (outType.isAFP()) { if (inType.isFloat()) { if (outType.afpPrecision() >= 0) { outCode = "(int)(" + inCode + " * 1.6 * (1 << " + QString::number(outType.afpPrecision()) + "))"; } else { outCode = "(int)(" + inCode + " * 1.6 / (1 << " + QString::number(-outType.afpPrecision()) + "))"; } } else if (inType.isAFP()) { int numLeftShifts = outType.afpPrecision() - inType.afpPrecision(); if (numLeftShifts > 0) { outCode = "(" + inCode + ") << " + QString::number(numLeftShifts); } else { outCode = "(" + inCode + ") >> " + QString::number(-numLeftShifts); } } else if (inType.isInt()) { if (outType.afpPrecision() >= 0) { outCode = "(" + inCode + ") << " + QString::number(outType.afpPrecision()); } else { outCode = "(" + inCode + ") >> " + QString::number(-(outType.afpPrecision())); } } else { outCode = inCode; // error condition } } else if (outType.isInt()) { if (inType.isFloat()) { return c_exp(); // error condition } else if (inType.isAFP()) { return c_exp(); // error condition } else if (inType.isInt()) { outCode = inCode; } else { outCode = inCode; // error condition } } return c_exp(outCode, outType); }
DataType moreGeneralType(DataType a, DataType b) { if (a.isFloat() || b.isFloat()) { return DATATYPE_FLOAT; } else if (a.isAFP() && b.isAFP()) { return DATATYPE_AFP(qMin(a.afpPrecision(), b.afpPrecision())); } else if (a.isAFP()) { return DATATYPE_AFP(a.afpPrecision()); } else if (b.isAFP()) { return DATATYPE_AFP(b.afpPrecision()); } else { return DATATYPE_INT; } }