为什么我不能在不进行任何转换的情况下将浮点数放入任何类型的 ptr 中?
Why can't I put a float into a ptr of any type without any kind of conversion going on?
我目前正在为我的编译器项目编写运行时,我想要通用且易于使用的结构来编码不同类型的结构(源语言是方案(。
我目前的方法是:
struct SObj {
SType type;
uint64_t *value;
};
指针始终是 64 或 32 位宽,所以不应该在我的值中放入浮点数吗?然后,如果我想要浮点数的实际值,我只需获取原始字节并将它们解释为浮点数。
提前谢谢。
不是真的。
当你写C++时,你正在对抽象进行编程。您正在描述一个程序。与流行的看法相反,它不是"所有字节"。
编译器很复杂。他们可以并且将会假设您遵循规则,并使用该假设来生成最有效的"实际"代码(阅读:机器代码(。
其中一条规则是uint64_t*
是指向uint64_t
的指针。当你把任意位塞进去时——无论它们是否与形成有效float
的位相同,还是其他东西——它就不再是一个有效的指针,简单地评估它有未定义的行为。
有一些语言设施可以做你想做的事,比如union
。但是您必须小心不要违反别名规则。您将存储一个标志(大概,这就是您的type
(,告诉您正在使用哪个union
成员。让生活更轻松,而是有一个std::variant
,它会为你做这一切。
话虽如此,您可以std::memcpy
/std::copy
位输入和复制位,只要它们是您在系统上选择的类型的有效表示,就可以uint64_t
。只是不要指望reinterpret_cast
是有效的:它不会。
指针始终为 64 或 32 位宽
不。
那么,难道不应该从字面上将浮点数放入我的价值中吗?
是的,这是可能的,尽管强烈建议不要这样做。C++有很多其他设施,所以你不必自己做这些事情。无论如何,您可以将指针内的字节解释为另一种类型。喜欢这个:
static_assert(sizeof(float*) >= sizeof(float));
static_assert(std::is_pod<float>::value == true); // overdramatic
float *ptr; // just allocate sizeof(float*) bytes on stack
float a = 5;
// use the memory of the pointer to store float value
std::memcpy(&ptr, &a, sizeof(float));
float b;
std::memcpy(&b, &ptr, sizeof(float));
a == b; // true
相关文章:
- 在C++中,将大的无符号浮点数四舍五入为整数的最佳方法是什么
- 如何修复此错误:未定义对"距离(浮点数,浮点数,浮点数,浮点数,浮点数)"的引用
- C++浮点数据类型和字符串数据类型无法子到模板函数中
- 使用提升将数据从 PyObject 复制到浮点数 *
- 使用浮点数和双精度数的非常小数字的数学
- 使用英特尔内联函数将打包的 8 位整数乘以浮点数向量
- 如何在 c++ 中将小数点后两位数的浮点数分配给另一个浮点数
- 返回浮点数的小数位数
- txt 文件中浮点数的最大和最小值
- 为什么 std::cout 打印浮点数、双精度和长双精度到相同的小数精度?
- 将浮点数转换为无符号字符数组并打印出来
- 如何将时间字符串 (M:SS) 转换为浮点数
- 如何将浮点数(*)[6]转换为浮点**类型?
- C++将浮点数乘以分数
- 如何将浮点数转换为uint8_t?
- 将字符串转换为浮点数或整数,而无需使用内置函数(如 atoi 或 atof)
- 如何在C++(Arduino)中将浮点数组转换为字节数组
- 为什么我不能在不进行任何转换的情况下将浮点数放入任何类型的 ptr 中?
- 尚未操作的 32 位规范化浮点数在任何平台/编译器上是否相同?
- 无需任何库函数即可将浮点数转换为字符串的有效方法