我有一个充满float32
的NEON寄存器。我想将它们四舍五入到最接近的整数,而不必转回主CPU。将float32
转换为uint32
的NEON指令只是截断,例如39.7
变为39
,而不是40
。我并不关心0.5
如何处理 - 从零或圆到圆,甚至两者都适合我。
我可以看到实现舍入的最佳途径是
int32
(因此截断)float32
int32
添加1,转换回float32
,并留出以防万一我们正在整理0.5
比较(不需要abs值,因为我知道在我的情况下他们都是正面的)这看起来很丑陋,缓慢而复杂。
是否有更清洁,更快捷,更简洁,更健全的方式?
答案 0 :(得分:6)
添加.5并转换为整数。如果希望结果采用浮点格式,请转换回来。
由于您知道数字都是正数,因此另一个选项是添加0x1p23并减去0x1p23。添加0x1p23的结果至少为0x1p23,因此float结果没有值小于1的位,因此它必须舍入为整数。然后减去0x1p23减去添加的值,只留下舍入的效果。
答案 1 :(得分:0)
浮点数到整数需要加或减0.5,具体取决于正数或负数。在Neon中,1.我可以提取值的符号; 2.位或为0.5,则0.5为正号; 3.添加带有原始值的带符号0.5:
// 1. extract sign of origin value
int32x4_t reinterpretInt = vreinterpretq_s32_f32(inputFloat);
int32x4_t signExtract = vdupq_n_s32(-2147483648);
int32x4_t signSignal = vandq_s32(reinterpretInt, signExtract);
// 2. bit-or with 0.5 with origin value
float32x4_t roundValue = vdupq_n_f32(0.5);
float32x4_t plusValue = vreinterpretq_f32_s32(vorrq_s32(vreinterpretq_s32_f32(roundValue), signSignal));
// 3. add signed
return vaddq_f32(inputFloat, plusValue);