如何获得-nan的十六进制值

时间:2018-05-20 19:49:49

标签: c++ floating-point nan

我在intel intrinsics中编写了一些代码,并且做了这个:

#include <iostream>
#include <xmmintrin.h>

float data[4];
__m128 val1 = _mm_set_ps1(2);
__m128 val2 = _mm_set_ps1(1);
val1 = _mm_cmpgt_ps(val1, val2);
_mm_store_ps(data, val1);

std::cout << std::hex << data[0];

我试图在SSE内在函数(即-nan)中获取“true”的十六进制值,但每当我尝试打印-nan的十六进制值时,只能将-nan作为“十六进制值”。 / p>

我也尝试过使用std :: oct和std :: dec,但这些都不起作用。

我还尝试在不同的组合中比较0xFFFFFFFF和数据[0],并得到了这个:

float data[4];
__m128 val1 = _mm_set_ps1(2);
__m128 val2 = _mm_set_ps1(1);
val1 = _mm_cmpgt_ps(val1, val2);
_mm_store_ps(data, val1);

float f = 0xFFFFFFFF;
float g = 0xFFFFFFFF;
std::cout << std::dec << (data[0] == f) << "\n"; // Prints "0"

std::cout << std::dec << (data[0] == data[0]) << "\n"; // Prints "0"

std::cout << std::dec << (f == g); // Prints "1"

有没有办法让我打印-nan的十六进制值,如果没有,有人可以告诉我-nan的二进制,十六进制等值吗?

3 个答案:

答案 0 :(得分:2)

根据IEEE规范,NaN是一个浮点值,其所有指数位都设置为“1”。

因此, all 设置为“1”的位的值也将是NaN。

如果要查看原始字节,只需打印原始字节:

#include <cmath>
#include <iomanip>
#include <iostream>
#include <sstream>

template<typename T>
std::string get_hex_bytes(T x) {
    std::stringstream res;
    auto p = reinterpret_cast<const unsigned char*>(&x);
    for (int i = 0; i < sizeof(x); ++i) {
        if (i)
            res << ' ';
        res << std::setfill('0') << std::setw(2) << std::hex << (int)p[i];
    }
    return res.str();
}

int main() {
    float data = NAN;
    std::cout << get_hex_bytes(data) << std::endl;
}

在小端机器上将打印如下内容:

00 00 c0 ff

P.S。 float f = 0xFFFFFFFF;不会将所有位都设置为“1”,它只是将整数0xFFFFFFFF转换为浮点表示(完全可以表示精度损失)。

答案 1 :(得分:1)

首先,没有&#34;否定nan&#34;。根据定义,nan不是数字。你无法否定它。 -nannan相同。

没有完全符合标准的方法来获取浮点值所包含的基础位,但最接近的是memcpy。只需从指向floatdouble的指针复制到指向等效大小的无符号整数类型的指针,然后打印std::hex活动的那个。

答案 2 :(得分:1)

正如手册所说,_mm_cmpgt_ps(具有特定比较谓词的cmpps),

  

对源操作数中的压缩单精度浮点值执行SIMD比较(第二个   操作数)和目标操作数(第一个操作数)并将比较结果返回到目标   操作数。比较谓词操作数(第三个操作数)指定在每个上执行的比较类型   包装值对。 每次比较的结果是所有1的双字掩码(比较真实)或全部   0s(比较错误)。比较时忽略零符号,因此-0.0等于+0.0。

(强调补充)

&#34;所有1s&#34;或十六进制的0xFFFFFFFF(因为它每个元素的32位)具有符号位设置(因此有正当理由打印-在这个数字可能是的任何其他前面签名)并且因为指数是全1且有效数不为零,所以它也是NaN。 NaN-ness通常不是非常相关,此结果的主要用途是作为按位运算的掩码(例如_mm_and_ps_mm_blendv_ps等),它们不关心NaN的特殊语义。