如何将 double 转换为 float 指针?

5

我正在尝试将双精度浮点型转换为浮点型指针,但是我不知道正确的方法。

这是我的代码:

#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

我应该如何正确地将双精度浮点数转换为浮点数指针?

补充:我期望得到的结果是20


8
你不能这样做。你实际想要解决什么问题?这是一个 XY 问题 吗? - Jabberwocky
5
当您将指向复合64位表示法(尾数、指数)的指针转换为指向不同的 32位表示法的指针,并在新表示法之后解释指向的内存时,您期望发生什么?转换值是一回事,转换指针是完全不同的事情。 - DevSolar
3
话虽如此,我不理解为什么要投反对票。这个问题问得很好,并附带了代码片段。我们难道不能再问好问题吗? - Bathsheba
4
我也不理解为什么有人会因为“不清楚你在问什么”而投下关闭票。他的问题非常明确。 - Jabberwocky
3
这个问题已经自带了正确答案。我觉得真正的问题是,为什么输出结果与预期不同。最初这个问题甚至没有说明预期输出是什么。 - M.M
显示剩余10条评论
5个回答

9

请考虑:

#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

解释:

这是一个值为10的double的内部表示。

double *转换为float *时,您只查看其前四个字节-0 0 0 0。你明白为什么当你引用指针时会得到一个0输出吗?

(除了像其他人指出的那样,因为破坏了严格别名的规定而使指针解引用行为未定义。)

解决方案:

你可能想要转换d

static_cast<float>(d);

然后,您可以将该值存储在正确类型的对象中:

float f = static_cast<float>(d);
float * fp = &f;

1
@ZackLee:IEEE标准754浮点数有一个很好的内部表示解释,如果你感兴趣的话。 - DevSolar
点赞给 @M.M 指出了严格别名的破坏。 - DevSolar

4
行为是未定义的:语言没有提供这样做的方法。例如,sizeof(float*)不必与sizeof(double*)相同。C++旨在最大程度地灵活使用。
您可以将double的地址强制转换为const unsigned char*指针,并以此方式读取内存。
否则,您需要转向汇编语言,在CPU级别上,指向类型和整数类型之间的区别相当模糊。
如果您想将double转换为float,请写
double d = 10; float f = d;

4

您的指针转换代码是正确的。

错误在于*f,它通过违反严格别名规则引起未定义行为。 您不能通过具有错误类型的指针读取或写入对象。(有一小部分例外)


1
您想要做的是一个 narrowing 的 static_cast:
auto f = static_cast<float>(d);
float* pointer = &f;

使用reinterpret_cast将失败,因为它不会让编译器将一个double的二进制表示更改为float的二进制表示。它实际上会重新解释双精度值为浮点数,导致奇怪和未定义的结果,因为表示不同。static_cast则会为您处理正确调整表示,可能会截断最低有效位。之后,您可以安全地使用浮点变量的地址,并使用指针访问该值。

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接