RT
vabs_s16会保留-32768。
我在aarch64下测试如下代码:
#include <arm_neon.h> #include <stdio.h> #include <stdint.h> int16_t foo(int16_t x) { int16x8_t ax; for (int i; i < 8; i++) { ax[i] = x; } ax = vabsq_s16(ax); return ax[0]; } int main(void) { int16_t x1 = -32768; int16_t x2 = -32767; printf("%d\n", foo(x1)); printf("%d\n", foo(x2)); return 0; }
输出:
-32768 32767
谢谢管理员帮我提交的问题,这个问题是我问的。
vabs_s16/s32的返回值看 arm-neon.h的定义是 int16x /int32x ,
如果后续的操作是vmax,如果继续使用vmax_s16/s32会导致 最大值丢失。
实际代码里面这样的操作比较常见。
因此建议 vabs_s16 之类的返回值设置成 uint16x / uint32x 这样,以免丢失 -32768/-2xxxxx .
也可以通过vreinterpret达到最大值不丢失,比如:
#include <arm_neon.h> #include <stdio.h> #include <stdint.h> uint16_t foo(int16_t x) { int16x8_t ax; printf("ax:"); for (int i = 0; i < 8; i++) { ax[i] = x + i; printf("%d ", ax[i]); } printf("\n"); uint16x8_t bx; ax = vabsq_s16(ax); bx = vreinterpretq_u16_s16(ax); return vmaxvq_u16(bx); } int main(void) { int16_t x1 = -32768; printf("max of abs(ax):%u\n", foo(x1)); return 0; } //output: //ax:-32768 -32767 -32766 -32765 -32764 -32763 -32762 -32761 //max of abs(ax):32768
我现在就是这么处理的。只是建议如果返回值定义修改成uint可能会更好。
了解