我有以下modf
使用 SSE 内在函数的工作实现,但是__m128i
当我需要将结果作为__m128
.
__m128 integer = _mm_cvtepi32_ps(_mm_cvttps_epi32(value));
__m128 fraction = _mm_sub_ps(value, integer);
是否存在没有类型转换的截断指令,或者一些幻数破解?
我有以下modf
使用 SSE 内在函数的工作实现,但是__m128i
当我需要将结果作为__m128
.
__m128 integer = _mm_cvtepi32_ps(_mm_cvttps_epi32(value));
__m128 fraction = _mm_sub_ps(value, integer);
是否存在没有类型转换的截断指令,或者一些幻数破解?
使用 SSE4.1,您可以使用roundps
和roundpd
指令:
// Single Precision
__m128 integer = _mm_round_ps(value,_MM_FROUND_TRUNC);
__m128 fraction = _mm_sub_ps(value,integer);
// Double Precision
__m128d integer = _mm_round_pd(value,_MM_FROUND_TRUNC);
__m128d fraction = _mm_sub_pd(value,integer);
这将分隔整数和小数部分,同时保留它们的符号。
同样,对于 AVX:
// Single Precision
__m256 integer = _mm256_round_ps(value,_MM_FROUND_TRUNC);
__m256 fraction = _mm256_sub_ps(value,integer);
// Double Precision
__m256d integer = _mm256_round_pd(value,_MM_FROUND_TRUNC);
__m256d fraction = _mm256_sub_pd(value,integer);
如果您还拥有 XOP 指令集,则只需一条指令(通过_mm256_frcz_pd
和系列)即可单独获得小数部分。
但是如果没有 SSE4.1,那么除了转换或执行 +/- 幻数技巧之外,真的没有更好的方法来做到这一点。(两者都会在溢出的情况下遇到问题)