将“__m256 with random-bits”转换为 [0, 1] 范围内的浮点值
Convert "__m256 with random-bits" into float values of [0, 1] range
我有一个包含随机位的 __m256
值。
我想“解释”它,以获得另一个包含 float
的 __m256
统一[0.0f, 1.0f]
范围内的值。
计划使用:
__m256 randomBits = /* generated random bits, uniformly distribution */;
__m256 invFloatRange = _mm256_set1_ps( numeric_limits<float>::min() ); //min is a smallest increment of float precision
__m256 float01 = _mm256_mul(randomBits, invFloatRange);
//float01 is now ready to be used
问题一:
但是,在 randomBits
的所有位都为 1 因此是 NAN 的极少数情况下,这会导致问题吗?
我能做些什么来保护自己免受这种伤害?
我希望 float01
始终是一个可用的数字
问题二:
通过上述方法得到的[0 to 1]范围是否保持统一?我知道 float 在不同的幅度下具有不同的精度
正如@Soonts 所指出的,可以在 [0, 1] 范围内统一创建浮点数:
我最终使用了以下答案:
//converts __m256i values into __m256 values, that contains floats in [0,1] range.
//
inline void int_rand_int_toFloat01( const __m256i* m256i_vals,
__m256* m256f_vals){ //<-- stores here.
const static __m256 c = _mm256_set1_ps(0x1.0p-24f); // or (1.0f / (uint32_t(1) << 24));
__m256i* rnd = ((__m256i*)m256i_vals);
__m256* output = ((__m256*)m256f_vals);
// remember that '_mm256_cvtepi32_ps' will convert 32-bit ints into a 32-bit floats
__m256 converted = _mm256_cvtepi32_ps(_mm256_srli_epi32(*rnd, 8));
*output = _mm256_mul_ps( converted, c);
}
将 int32_t 重新解释为浮点数,可以
auto const one = _mm256_set1_epi32(0x7f800000);
a = _mm256_and_si256(a, _mm256_set1_epi32(0x007fffff));
a = _mm256_or_si256(a, one);
return _mm256_sub_ps(_mm256_castsi256_ps(a), _mm256_castsi256_ps(one));
and/or 序列将重复使用输入序列的 23 个 LSB,以在 1.0f <= a < 2.0f 之间产生均匀分布的值。然后去掉1.0f的偏置。
我有一个包含随机位的 __m256
值。
我想“解释”它,以获得另一个包含 float
的 __m256
统一[0.0f, 1.0f]
范围内的值。
计划使用:
__m256 randomBits = /* generated random bits, uniformly distribution */;
__m256 invFloatRange = _mm256_set1_ps( numeric_limits<float>::min() ); //min is a smallest increment of float precision
__m256 float01 = _mm256_mul(randomBits, invFloatRange);
//float01 is now ready to be used
问题一:
但是,在 randomBits
的所有位都为 1 因此是 NAN 的极少数情况下,这会导致问题吗?
我能做些什么来保护自己免受这种伤害?
我希望 float01
始终是一个可用的数字
问题二:
通过上述方法得到的[0 to 1]范围是否保持统一?我知道 float 在不同的幅度下具有不同的精度
正如@Soonts 所指出的,可以在 [0, 1] 范围内统一创建浮点数:
我最终使用了以下答案:
//converts __m256i values into __m256 values, that contains floats in [0,1] range.
//
inline void int_rand_int_toFloat01( const __m256i* m256i_vals,
__m256* m256f_vals){ //<-- stores here.
const static __m256 c = _mm256_set1_ps(0x1.0p-24f); // or (1.0f / (uint32_t(1) << 24));
__m256i* rnd = ((__m256i*)m256i_vals);
__m256* output = ((__m256*)m256f_vals);
// remember that '_mm256_cvtepi32_ps' will convert 32-bit ints into a 32-bit floats
__m256 converted = _mm256_cvtepi32_ps(_mm256_srli_epi32(*rnd, 8));
*output = _mm256_mul_ps( converted, c);
}
将 int32_t 重新解释为浮点数,可以
auto const one = _mm256_set1_epi32(0x7f800000);
a = _mm256_and_si256(a, _mm256_set1_epi32(0x007fffff));
a = _mm256_or_si256(a, one);
return _mm256_sub_ps(_mm256_castsi256_ps(a), _mm256_castsi256_ps(one));
and/or 序列将重复使用输入序列的 23 个 LSB,以在 1.0f <= a < 2.0f 之间产生均匀分布的值。然后去掉1.0f的偏置。