如何实现具有不同情况的交换机?

时间:2014-08-09 11:46:25

标签: c

如果最后一个条件为真,那么在以下程序中,我们必须检查之前的所有条件。 在下面的程序中是否有可能实现开关盒? 我将非常相似的代码转换为Arm组件。

main()
{
    int x;

    if (x< 32768)
        x<<15;
    elseif(x<49152)
        (x<<12)- 7;
    elseif(x<53248)
        (x<<11)- 13;
    elseif(x<59392)
        (x<<10)-27;
    elseif(x<60928)
        (x<<9)-61;
    elseif(x<62208)
        (x<<8)-139;
    elseif(x<64128)
        (x<<7)-225;
    elseif(x<65088)
        (x<<6)-414;
    elseif(x<65344)
        (x<<5)-801;
    elseif(x<65488)
        (x<<4)-1595;
    elseif(x<65512)
        (x<<3)-2592;
    elseif(x<65524)
        (x<<2)-4589;
    elseif(x<65534)
        (x<<1)-8586;
}

希望有人能帮助我。

2 个答案:

答案 0 :(得分:4)

您无法使用开关执行此操作,因为您需要使用常量值来与x进行比较,而不是布尔条件。但你可以使用这样的结构:

struct {
   int u_limit;
   int shift_left;
   int add;
} ranges[13] = { {32768, 15, 0}, {49152, 12, -7} /*, ...*/};

for (int i = 0; i < 13; i++) {
   if (x < ranges[i].u_limit) {
      x = x << ranges[i].shift_left + ranges[i].add; break;
   }
}

当然,你可以用二进制搜索替换线性搜索以获得一些加速。

答案 1 :(得分:4)

首先要做的事情是:你关注性能吗?如果是这样,您是否有实际分析数据显示此代码是热点,并且没有其他内容显示在配置文件中?

我对此表示怀疑。事实上,我愿意睡觉,你甚至没有对它进行基准测试。您正在查看代码并尝试对其进行微观优化。

如果是这种情况,那么答案很简单:停止这样做。以编写代码的方式编写代码,并专注于提高代码的算法效率。让编译器担心优化事情。如果性能证明不足那么配置文件并关注分析的结果。几乎总是能够解决您的性能问题:选择性能更佳的算法。答案几乎永远不会“修补if声明”。

现在,回答你的问题:switch在这种情况下无用,因为没有理智的方式来表示x < 32768中的概念case }语句,没有为x的每个这样的值写一个语句。显然这是实际的,也不是理智的。

更重要的是,你似乎在错误的观念下运作,switch会转化为更少的比较。在一些罕见的情况下,编译器可以避免比较,但大多数时候switch将表示与case语句一样多的比较。因此,如果您需要使用switch针对10000个不同的可能值检查变量,您将获得10000次比较。

在您的情况下,您正在检查超过10,000个可能值的方式,因此简单的if构造与“小于”运算符相结合更有意义,并且比{{{ {1}}。

你写了“如果最后一个条件为真,那么在跟随的程序中这就不必要了,我们必须检查它之前的所有条件。”是的,你做到了。您可以重写它,以便如果最后一个条件为真,您只需要进行两次比较。但是你只需要解决它的问题:如果switch你最终必须检查所有其他可能的值,那么你就会回到你开始的地方。

一种可能的解决方案是执行二分查找。这肯定有资格作为算法改进,但是如果没有硬数据,这确实是一个热点,这将是一个相当愚蠢的练习。

最重要的是:编写正确易于理解且易于维护和改进的代码,并且不必担心重新排序x< 32768语句。 perreal的出色答案显示了简单易懂和维护代码的一个很好的例子。

关于编写正确代码的主题,C和C ++中没有if这样的东西。这让我们最后一点:在微优化代码之前至少尝试运行编译器。