如何用预先计算的十六进制值初始化双数组
How to initialize a double array with the precalculated hex values?
我想实现浮点数字数组的初始化。使用预先计算的十六进制值。结果与此类似:
double arr[3];
memcpy(&arr[0], "xe3x3bxefxf6xc1x78xc6x3fxf9x37x5ax8dxfdxaex75x3fx62xe9x58x48x4fx49xc6x3f",24);
我希望这样的初始化是在一行中完成的。比如,在这个例子中(但在我的例子中是浮点数字):
const char s[] = "x48x69x21";
这在语法上可能吗?
更接近的是一个联合。问题是字符串litral的最后一个字符有一个null,但这应该有效:
union {
char chr[3 * sizeof(double) + 1];
double arr[3];
} val = { "xe3x3bxefxf6xc1x78xc6x3fxf9x37x5a"
"x8dxfdxaex75x3fx62xe9x58x48x4fx49xc6x3f" };
简单地说,因为它使用了一个额外的字节,就会浪费一些内存(通常是32位机器上的4个字节)
参考标准:
在C中,一份(非规范性)说明称其应适用于6.5.2.3结构和工会成员
如果用于访问联合对象内容的成员与上次用于在对象中存储一个值,该值的对象表示的适当部分将被重新解释作为新类型中的对象表示,如6.2.6所述(有时称为"类型"的过程punning")
我找不到任何关于C++是否允许的引用,但所有常见的编译器都接受它。我能找到的更相关的是
9.5工会【工会类别】
在并集中,任何时候最多可以有一个非静态数据成员处于活动状态,即at的值大多数非静态数据成员可以在任何时候存储在联合中。。。联合对象的所有非静态数据成员都具有相同的地址。
这解释了为什么它可以工作
和:
3.10左值和右值[basic.lval]
§10如果程序试图通过除以下类型的行为未定义。。。【未引用工会访问权限】
这清楚地表明它会导致未定义的行为。问题是,在C6.5表达式§7…中也存在相同的段落(称为严格混叠规则)
TL/DR:联合方式在C中是明确有效的,在C++中可能是UB,所以我的建议是把它放在链接到C++程序的C编译单元中。
C++20在C++中带来了一种非常需要的类型双关方法,而不是UB。您现在可以执行以下操作。高兴
double arr[] = {
std::bit_cast<double>(0xE33BEFF6C178C63F),
std::bit_cast<double>(0xF9375A8DFDAE753F),
std::bit_cast<double>(0x62E958484F49C63F)
};
我建议使用十六进制浮点文字而不是位模式
double arr[] =
{
-0x1.beff6c178c63fp564, // 0xE33BEFF6C178C63F
-0x1.75a8dfdae753fp916, // 0xF9375A8DFDAE753F
0x1.958484f49c63fp559, // 0x62E958484F49C63F
};
相关文章:
- 是否可以在编译时初始化数组,以便在运行时不会花费时间?
- 在函数内部的声明中初始化数组,并在外部使用它
- 为什么用结构初始化数组需要指定结构名称
- 有没有一种代码密度较低的方法来使用非默认构造函数初始化数组?
- C++使用另一个数组和新值初始化数组
- 初始化数组、"memset"或" {//value} "的最佳方法是什么?
- 在 constexpr 构造函数中初始化数组是否合法?
- 我可以初始化 const 实例,以便我可以将其用作 const 来初始化数组吗?
- 在构造函数中初始化数组
- 是否可以使用函数返回的值初始化数组
- 使用宏使用额外元素初始化数组
- 在循环中显示不同值的初始化数组
- 如何在macOS中的旧扩展clang和gcc编译器中初始化数组和向量
- 使用可变模板列表初始化数组,并放置new
- 使用函数从 Visual Studio 2017 中的 main 创建和初始化数组
- 使用 c++ 中的函数初始化数组
- 这是使用构造函数初始化数组对象的最佳方法吗?
- C++ 使用变量而不是常量表达式初始化数组
- 在初始化列表中初始化数组的更好方法
- 在可变参数模板类中初始化数组