如何将double转换为float指针?

时间:2017-11-10 08:28:53

标签: c++ pointers casting

我正在尝试将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

5 个答案:

答案 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级别,指向类型的指针和整数类型之间的区别相当模糊。

如果您想转换 doublefloat,请写

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;
}