c++ - How do I clamp __m128i signed integers into non-negative unsigned integers in SSE
问题描述
I can't figure out how to convert 4 x 32 bit signed integers stored in a single __m128i into "unsigned" counterparts. The conversion should be done with value truncation, clamping negative numbers to 0 but leaving non-negative numbers unchanged.
E.g: -100 should turn into 0, while 100 should remain 100
#include <stdio.h>
#include <cstdint>
#include <emmintrin.h>
int main()
{
alignas(16) uint32_t out32u[4];
__m128i my = _mm_setr_epi32 (100, -200, 0, -500);
<....missing code....>
_mm_store_si128(reinterpret_cast<__m128i *>(out32u), my);
printf("%u %u %u %u\n", out32u[0], out32u[1], out32u[2], out32u[3]);
}
So given the
<....missing code....>
additions the result of the code above should become:
100 0 0 0
解决方案
Use SSE4.1 _mm_max_epi32
as:
my = _mm_max_epi32(my, _mm_setzero_si128());
Or without that, @chtz's elegant a & ~(a >> 31)
can be implemented using SSE2 as follows:
my = _mm_andnot_si128(_mm_srai_epi32(my, 31), my);
Replace <....missing code....>
with the above line.
推荐阅读
- javascript - AVA 单元测试未通过 Javascript 测试规范
- python - 编写一个函数,接收一个整数列表,如果它按顺序包含 007,则返回 True
- php - 关于如何检查子表是否具有某些多个值的雄辩或 SQL 方式
- python-3.x - python-vlc 不播放和响应 youtube 视频链接?
- laravel - laravel 验证数组和缺失参数
- php - Laravel 关系不起作用。没有调用关系方法
- java - 如何从数组列表中删除按钮单击时的列表视图项?
- firebase-cloud-messaging - firebase 通知只允许从我的域发送
- postgresql - 如何上传多个巨大的 CSV 文件并合并它们?
- types - 为什么索引显式类型的向量会因类型推断错误而失败?