如何使用预先计算的十六进制值初始化双数组?

时间:2017-01-05 14:37:33

标签: c++ floating-point hex double

我想实现浮点数数组的初始化。使用预先计算的十六进制值。结果与此类似:

double arr[3];
memcpy(&arr[0], "\xe3\x3b\xef\xf6\xc1\x78\xc6\x3f\xf9\x37\x5a\x8d\xfd\xae\x75\x3f\x62\xe9\x58\x48\x4f\x49\xc6\x3f",24);

我希望这样的初始化是在一行中完成的。就像在这个例子中一样(但对于我的情况下的浮点数):

const char s[] = "\x48\x69\x21";

语法是否可行?

3 个答案:

答案 0 :(得分:1)

更接近的是工会。问题是字符串litteral的最后一个字符为null,但这应该有效:

union {
    char chr[3 * sizeof(double) + 1];
    double arr[3];
} val = { "\xe3\x3b\xef\xf6\xc1\x78\xc6\x3f\xf9\x37\x5a"
    "\x8d\xfd\xae\x75\x3f\x62\xe9\x58\x48\x4f\x49\xc6\x3f" };

因为它使用了一个额外的字节会浪费一些内存(通常是32位机器上的4个字节)

参考标准:

在C a(非规范性)注释中说它应该适用于6.5.2.3结构和联盟成员

  

如果用于访问union对象内容的成员与上次使用的成员不同   在对象中存储一个值,该值的对象表示的相应部分被重新解释   作为6.2.6中描述的新类型中的对象表示(有时称为“类型”的过程)   双关“)

我找不到C ++的任何参考说明是否允许,但所有常见的编译器都接受它。我能找到的相关性更高

9.5联盟[class.union]

  

在联合中,最多一个非静态数据成员可以随时处于活动状态,即at的值   大多数非静态数据成员可以随时存储在一个联合中......联合对象的所有非静态数据成员都具有相同的地址。

解释了它可以运作的原因

3.10左值和右值[basic.lval]

  

§10如果一个程序试图通过一个以外的glvalue来访问一个对象的存储值   以下类型的行为未定义... [联合访问未引用]

明确表示会导致未定义的行为。问题是C 6.5表达式中存在同一段(称为严格别名规则)......

TL / DR:联合方式在C语言中明显有效,在C ++中可能是UB,所以我的建议是将它放在一个链接到C ++程序的C编译单元中。

答案 1 :(得分:0)

C++20 在 C++ 中带来了一种急需的非 UB 类型双关方法。您现在可以执行以下操作。欢喜。

double arr[] = {
    std::bit_cast<double>(0xE33BEFF6C178C63F),
    std::bit_cast<double>(0xF9375A8DFDAE753F),
    std::bit_cast<double>(0x62E958484F49C63F)
};

答案 2 :(得分:0)

我建议使用 hex floating-point literals 而不是位模式

double arr[] =
{
    -0x1.beff6c178c63fp564, // 0xE33BEFF6C178C63F
    -0x1.75a8dfdae753fp916, // 0xF9375A8DFDAE753F
    0x1.958484f49c63fp559,  // 0x62E958484F49C63F
};