【问题标题】:How to cast double to float pointer?如何将double转换为浮点指针?
【发布时间】:2017-11-10 08:28:53
【问题描述】:

我正在尝试将 double 转换为浮点指针,但我不知道正确的方法。

这是我的代码

#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

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

ADD : 我期望得到的结果是 20

【问题讨论】:

  • 你不能这样做。您实际上试图解决什么问题?这是XY Problem吗?
  • 当您将指向复杂 64 位表示(尾数、指数)的指针转换为指向 不同、32 位表示的指针和然后解释新表示后指向的内存?转换值是一回事,转换指针……完全是另一回事。
  • 也就是说,我不明白反对意见。这个问题问得很好,代码是sn-p。难道我们不能再问好问题了吗?
  • 我也不明白“不清楚你在问什么”的原因。很清楚他在问什么。
  • @MichaelWalz 问题本身已经包含正确答案。在我看来,真正的问题是为什么输出与预期不同。最初这个问题甚至没有说明预期的输出。

标签: c++ pointers casting


【解决方案1】:

考虑:

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

【讨论】:

【解决方案2】:

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

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

【讨论】:

    【解决方案3】:

    行为是未定义:语言没有提供这样做的方法。例如,sizeof(float*) 不必与sizeof(double*) 相同。 C++ 旨在最大限度地提高灵活性。

    您可以将double 的地址转换为const unsigned char* 指针并以这种方式读取内存。

    否则你需要求助于汇编,在 CPU 级别,指向类型的指针和整数类型之间的区别相当模糊。

    如果您想将double转换float,然后编写

    double d = 10; float f = d;
    

    【讨论】:

      【解决方案4】:

      你要做的是缩小static_cast

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

      reinterpret_cast 的使用将失败,因为它不会发出编译器将double 的按位表示更改为float 的表示。它实际上会将双精度值重新解释为浮点数,由于表示不同,会产生奇怪和未定义的结果。另一边的static_cast 会照顾您,确保正确调整表示,如有必要,可能会截断最低有效位。在此之后,您可以安全地使用浮点变量的地址并通过指针访问该值。

      【讨论】:

        【解决方案5】:

        你想要的行为可以在 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;
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2012-09-06
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-04-01
          • 1970-01-01
          相关资源
          最近更新 更多