我正在开发一个嵌入式项目,我正在尝试删除已实现+ / - *的虚拟数字类。删除此类可以节省大量代码空间,因此我已将+替换为以下函数,
if (BASE(h)->type() == FLOAT && BASE(v)->type() == FLOAT)
{
res = FLOAT(h)->floatValue() + FLOAT(v)->floatValue();
}
else if (BASE(h)->type() == INTEGER && BASE(v)->type() == INTEGER)
{
res = INTEGER(h)->intValue() + INTEGER(v)->intValue();
}
else if (BASE(h)->type() == INTEGER && BASE(v)->type() == FLOAT)
{
res = INTEGER(h)->floatValue() + FLOAT(v)->floatValue();
}
else
{
res = FLOAT(h)->floatValue() + INTEGER(v)->floatValue();
}
有没有更简单的方法来实现这一目标?因为我必须对其他操作和比较使用相同的方案吗?
答案 0 :(得分:2)
如何分两步完成?
isInt1 = BASE(h)->type()==INTEGER;
isInt2 = BASE(v)->type()==INTEGER;
if (isInt1 && isInt2)
op1 = INTEGER(h)->intValue();
op2 = INTEGER(h)->intValue();
res = op1 + op2;
else {
op1 = isInt1 ? (FLOAT(h)->floatValue()) : (INTEGER(h)->floatValue());
op2 = isInt2 ? (FLOAT(v)->floatValue()) : (INTEGER(v)->floatValue());
res = op1 + op2;
}
答案 1 :(得分:2)
#define GETFLOAT(arg) (BASE(arg)->type() == INTEGER ? INTEGER(arg)->floatValue() : FLOAT(arg)->floatValue())
switch(BASE(h)->type()) {
case INTEGER:
if (BASE(v)->type() == INTEGER) {
res = INTEGER(h)->intValue() + INTEGER(v)->intValue();
break;
}
case FLOAT:
res = GETFLOAT(h) + GETFLOAT(v);
}
这实际上是h
类型的两次分支,但只有在(你在其他地方的评论中说)的情况下,无论如何都是昂贵的,浮点运算。你可以用goto
来避免这种情况,但我不会再有这个论点了。类似的东西:
switch(BASE(h)->type()) {
case INTEGER:
if (BASE(v)->type() == INTEGER) {
res = INTEGER(h)->intValue() + INTEGER(v)->intValue();
goto finished; // or better: return res;
}
hvalue = INTEGER(h)->floatValue()
break;
case FLOAT:
hvalue = FLOAT(h)->floatValue();
}
res = hvalue + GETFLOAT(v);
finished:
与霍华德的答案一样,如果BASE()
或type()
代价昂贵,那么即使它被使用了两次,你也可以计算每个参数的答案一次。
答案 2 :(得分:0)
我建议您重新考虑您的架构。你用这种方法节省了多少,而且性能成本是多少?您的新方法似乎将所有内容都推送到浮点数(您没有显示res
的声明,我认为它是float res;
。
检查此修复程序对(a+b)*c
之类的操作,其中a,b和c中的每一个都是整数。有了这个修复程序,你现在有一个浮点乘以一个int,这比一个int乘以int计算成本要高得多。
我建议使用模板并让C ++类型系统尽可能多地处理转换。这使您可以使用不必具有公共虚拟基类的不同存储类型。
您还可以通过仅实现int + float与float + int中的一个来减少程序大小(类似地使用int * float与float * int)。暂时实现int + float和float + int,但故意使一个引发编译时错误。翻转失败的操作数的顺序。