How does this function calculate the absolute value of a float using NOT and AND?

I am trying to understand how the following code snippet works. This program uses SIMD vector instructions (Intel SSE) to calculate the absolute value of 4 floats (so basically the fabs () vector function).

Here is a snippet:

#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;
}

Now I know that this works, since I myself ran the program to test it. When compiling with g ++ 4.8.2, the result is:

x[0]: 4
x[1]: 20
x[2]: 15
x[3]: 143

Three (related) questions will perplex me:

First, how is it generally possible to take a bitwise function and apply it on a float? If I try this in C ++ vanilla, it tells me that this only works for integral types (which makes sense).

, -, : ? ? Python : AND -1 ( 0) , . , ?

-, , , NAND ( ?), -0,0 0,0, . -0.0 ?

:

Intel

+4
1

-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. >

+5

Source: https://habr.com/ru/post/1541893/


All Articles