这个函数如何通过NOT和and操作来计算浮点数的绝对值
How does this function compute the absolute value of a float through a NOT and AND operation?
我试图理解下面的代码片段是如何工作的。该程序使用SIMD矢量指令(Intel SSE)来计算4个浮点数的绝对值(因此,基本上是一个矢量化的"fabs()"函数)。
下面是代码片段:#include <iostream>
#include "xmmintrin.h"
template <typename T>
struct alignas(16) sse_t
{
T data[16/sizeof(T)];
};
int main()
{
sse_t<float> x;
x.data[0] = -4.;
x.data[1] = -20.;
x.data[2] = 15.;
x.data[3] = -143.;
__m128 a = _mm_set_ps1(-0.0); // ???
__m128 xv = _mm_load_ps(x.data);
xv = _mm_andnot_ps(a,xv); // <-- Computes absolute value
sse_t<float> result;
_mm_store_ps(result.data, xv);
std::cout << "x[0]: " << result.data[0] << std::endl;
std::cout << "x[1]: " << result.data[1] << std::endl;
std::cout << "x[2]: " << result.data[2] << std::endl;
std::cout << "x[3]: " << result.data[3] << std::endl;
}
现在,我知道它是有效的,因为我自己运行了程序来测试它。当使用g++ 4.8.2编译时,结果是:
x[0]: 4
x[1]: 20
x[2]: 15
x[3]: 143
三个(相关的)问题困扰着我:
首先,怎么可能把一个按位函数应用到浮点数上?如果我在普通的c++中尝试这个,它告诉我这只适用于整型(这是有意义的)。
但是,第二,也是更重要的:它到底是怎么工作的?做NOT和and有什么用呢?在Python中尝试使用整数类型只会给你预期的结果:任何整数与-1(不是0),只是给你那个数字,但不改变符号。那么它是如何工作的呢?
第三,我注意到,如果我改变用于NAND操作的浮点数的值(用3标记),从-0.0到0.0,程序不再给我绝对值。但是-0.0怎么可能存在,它又有什么用呢?
有用的参考:
Intel intrinsic guide
-0.0
表示为1000...000
1。因此,_mm_andnot_ps(-0.0, x)
2等价于0111...111 & x
。这将强制MSB(即符号位)为0。
<子> 1。在IEEE-754中,子>
<子> 2。_mm_andnot_ps
本征并不意味着"NAND";参见http://msdn.microsoft.com/en-us/library/68h7wd02(v=vs.90).aspx。 子>
相关文章:
- 为什么"do while"循环不断退出,即使条件计算结果为 false?
- 为什么在popback()操作之后,它仍然打印完整的矢量
- 递归函数计算序列中的平方和(并输出过程)
- (C++)分析树以计算返回错误值的简单算术表达式
- 我的字符计数代码计算错误.为什么
- RPN计算器使用头文件进行计算操作和堆栈;用于堆栈的矢量
- 在进行顺序计算时保持操作顺序
- 根据堆栈操作 c++ 计算元素的最大数量
- 计算QuickSort算法中的基本操作
- QML:读取由计算着色器操作的缓冲区
- 如何计算特殊操作(Exp SIN SQRT)的FOP总数和浮点性能
- 常量操作是否在运行时计算
- 计算给定程序的基本操作
- 赋值操作在C中隐式计算为什么布尔值
- 关系和大多数合并操作计算
- 位操作:计算uint64_t中所有位(即 1 的数字)的总和
- 这个函数如何通过NOT和and操作来计算浮点数的绝对值
- 如何计算运行c++程序的实际操作次数
- 计算c++中操作之间的时间长度
- 位操作 - 如何在 C++ 中计算二进制位