如果短类型溢出,如何将float类型转换为short类型并截断float类型?

时间:2012-12-23 09:09:12

标签: c types casting

我有一个代码:

    if (Ly0 > 32767) {
        buffer[index] = 32767;
    } else if (Ly0 < -32768) {
        buffer[index] = -32768;
    } else {
        buffer[index] = (short) Ly0;
   }
  • buffer是短类型。
  • Ly0是浮动类型。

我需要将float转换为short,如果float的整数部分超过short short short short应该等于short short value,并且如果float的整数部分小于short short short short应该等于short min value,在其他我需要将float转换为short并获得float的整数值。

换句话说,我需要从float转换为short并截断float,如果它超出了short的范围。

问题是这种方法并不快,而且很快。

是否有任何更快,更干净的方式将float转换为short。

3 个答案:

答案 0 :(得分:3)

使用sse内在函数,您可以先转换为整数,然后执行long int到short int饱和转换(使用PACKSSDW)。

“便携式”方式是使用例如ORC,这是一个运行时编译库,用于优化内环,使用mmx,sse,neon和avs;以及提供兼容的串行实现。

甚至在此之前,可能需要检查编译器输出。例如。对于gcc -ffast-math -O3等,编译器通常可以生成已经xmm的指令并并行化大循环,其迭代计数在编译时是已知的。使用“luck == brute force”,可以将c代码调整为编译器可以识别饱和包模式的形式。通常它只取决于微观管理中间计算的类型。 (是比较有符号还是无符号,是int还是short等。)

答案 1 :(得分:0)

如果你有一个相当明亮的编译器,并且你实际上是在循环中这样做 - 假设你给编译器一个很好的“优化这个”的提示,那么它应该能够弄清楚你在做什么和使用“聪明”的指令,例如SSE / SSE2 - 假设你正在编译的处理器支持它,当然。

否则,使用编译器特定扩展或内联汇编程序将是您的选择 - gcc和MS编译器都具有执行此类操作的内部函数 - 或者,如建议的那样,可能有外部库可以很好地执行此操作。再次,假设有这种操作的处理器支持。

最后一个建议,可能是这样做(在某些处理器上)更快:

int x = Ly0;
if (x > 32767) x = 32767;
else if (x < -32768) x = -32768;
buffer[index] = (short)x; 

原因是浮点比较有时比整数更昂贵 - 并且编译器可以更好地优化此代码。但这并不能保证 - 一如既往地基准和比较。查看编译器输出并看看你认为它是否有意义永远不会伤害!

编辑:上面的代码假定这些值与您的预期范围相差不远。对于40亿以外的价值,它会出错。如果发生这种情况,那么无论如何都需要使用浮点比较。

答案 2 :(得分:-2)

可能没有办法优化代码的和平。我猜这个代码在一些周期内执行很多次,因为你有性能问题。您需要考虑优化周期。例如,如果Ly0值在随机访问容器中,则优化后可能会产生良好的结果。

for (int index = 0; index < (Ly0s.size() - 4); idx += 4) {
    do_conversion_for(index);
    do_conversion_for(index + 1);
    do_conversion_for(index + 2);
    do_conversion_for(index + 3);
}
switch (Ly0s.size() % 4){
    case 3:
        do_conversion_for(index + 3);
    case 2:
        do_conversion_for(index + 2);
    case 1:
        do_conversion_for(index + 1);
}

而不是

for (int index = 0; index < Ly0s.size(); ++idx) {
    do_conversion_for(index);
}