我正在尝试将double转换为float指针,但我不知道正确的方法。
这是我的代码
#include <iostream>
int main(int argc, const char * argv[]) {
// insert code here...
float *f;
double d = 10;
f = reinterpret_cast<float*>(&d);
d = 20;
std::cout << "RESULT : " << *f << std::endl;
return 0;
}
我得到以下结果。
RESULT : 0
Program ended with exit code: 0
如何正确地将double转换为浮点指针?
ADD:我期望得到的结果是20
答案 0 :(得分:7)
考虑:
#include <cstdio>
#include <cassert>
using namespace std;
int main()
{
double d = 10;
float f;
assert( sizeof d == 8 );
assert( sizeof f == 4 );
unsigned char * d_ = (unsigned char *)&d;
printf( "%hhx %hhx %hhx %hhx %hhx %hhx %hhx %hhx\n", d_[0], d_[1], d_[2], d_[3], d_[4], d_[5], d_[6], d_[7] );
}
至少在我的机器上,这给出了以下输出:
0 0 0 0 0 0 24 40
这是double
的内部代表,其值为10
。
通过将double *
转换为float *
,您只需查看此前四个字节 - 0 0 0 0
。当您取消引用指针时,您是否看到为什么获得0
输出?
(除此之外,正如其他人所指出的那样,由于破坏严格的别名,指针的解引用是未定义的行为。)
您可能想要的是投射d
的值:
static_cast<float>(d);
您可以然后将该值存储在正确类型的对象中:
float f = static_cast<float>(d);
float * fp = &f;
答案 1 :(得分:4)
行为未定义:语言无法执行此操作。例如,sizeof(float*)
不必与sizeof(double*)
相同。 C ++旨在最大限度地提高灵活性。
您可以将double
的地址转换为const unsigned char*
指针并以此方式读取内存。
否则你需要求助于汇编,在CPU级别,指向类型的指针和整数类型之间的区别相当模糊。
如果您想转换 double
到float
,请写
double d = 10; float f = d;
答案 2 :(得分:3)
投射指针的代码是正确的。
错误是*f
,它通过违反严格别名规则导致未定义的行为。您无法读取或写入指向它所指向的对象的类型错误的指针。 (有一小部分例外)。
答案 3 :(得分:1)
您想要做的是缩小static_cast
:
auto f = static_cast<float>(d);
float* pointer = &f;
reinterpret_cast
的使用将失败,因为它不会发出编译器来将double
的按位表示更改为float
的那个。它实际上会将double值重新解释为float,由于表示不同而产生奇怪和未定义的结果。另一方面static_cast
会照顾您正确调整表示,如果需要可能截断最低有效位。在此之后,您可以安全地使用float变量的地址并使用指针访问该值。
答案 4 :(得分:1)
您希望可以在C ++中实现的行为。但是,不是通过原始指针,而是C ++允许用户定义的类型。
class double_as_float {
double& d;
public:
double_as_float(double& d) : d(d) { }
float operator*() const { return static_cast<float>(d); }
};
用法:
#include <iostream>
int main() {
double d = 10;
double_as_float f { d };
d = 20;
std::cout << "RESULT : " << *f << std::endl;
return 0;
}