C 如果短类型为溢出,如何将浮点类型强制转换为短类型并截断浮点类型?

C 如果短类型为溢出,如何将浮点类型强制转换为短类型并截断浮点类型?,c,types,casting,C,Types,Casting,我有一个密码: if (Ly0 > 32767) { buffer[index] = 32767; } else if (Ly0 < -32768) { buffer[index] = -32768; } else { buffer[index] = (short) Ly0; } if(Ly0>32767){ 缓冲区[索引]=32767; }否则如果(Ly0

我有一个密码:

    if (Ly0 > 32767) {
        buffer[index] = 32767;
    } else if (Ly0 < -32768) {
        buffer[index] = -32768;
    } else {
        buffer[index] = (short) Ly0;
   }
if(Ly0>32767){
缓冲区[索引]=32767;
}否则如果(Ly0<-32768){
缓冲区[索引]=-32768;
}否则{
缓冲区[索引]=(短)Ly0;
}
  • 缓冲区
    为短类型
  • Ly0
    为浮点型
我需要将float转换为short,如果float的整数部分大于short max value short应该等于short max value,如果float的整数部分小于short min value short应该等于short min value,在其他情况下,我需要将float转换为short,只得到float的整数值

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

问题是这种方法不是很快,也不是很硬


是将float转换为short的最快捷、最干净的方法。

可能没有办法优化这种代码的和平。我猜这段代码在某个周期内执行了很多次,因为您有性能问题。你需要考虑优化循环。例如,如果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()-4);idx+=4){
对(索引)进行转换;
对(索引+1)进行转换;
对(索引+2)进行转换;
对(索引+3)进行转换;
}
开关(Ly0s.size()%4){
案例3:
对(索引+3)进行转换;
案例2:
对(索引+2)进行转换;
案例1:
对(索引+1)进行转换;
}
而不是

for (int index = 0; index < Ly0s.size(); ++idx) {
    do_conversion_for(index);
}
for(int index=0;index
使用sse Intrinsic,您可以先将其转换为整数,然后执行长整数到短整数饱和转换(使用)

“可移植”的方法是使用,例如,这是一个用于运行时编译的库,用于使用mmx、sse、neon和avs的优化内部循环;以及提供兼容的串行实现


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

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

否则,使用特定于编译器的扩展或内联汇编程序将是您的选择—gcc和MS编译器都有实现这类功能的内在函数—或者,正如所建议的,可能有外部库可以很好地实现这一点。同样,假设有处理器支持这种操作

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

intx=Ly0;
如果(x>32767)x=32767;
如果(x<-32768)x=-32768;
缓冲区[索引]=(短)x;
原因是浮点比较有时比整数比较昂贵,而编译器在优化这段代码方面可能做得更好。但这并不能保证——一如既往,基准测试和比较。查看编译器的输出,看看它是否也有意义,这是一件好事


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

我想你在第二个分支中漏掉了一个减号。仅仅改变代码的那一部分永远不会足够快。您需要显示整个循环,因为这是缓慢的,而不是上面的代码。
int x = Ly0;
if (x > 32767) x = 32767;
else if (x < -32768) x = -32768;
buffer[index] = (short)x;