简体   繁体   English

如何将双精度转换为浮动指针?

[英]How to cast double to float pointer?

I'm trying to cast double to float pointer but I don't know the proper way to do it.我正在尝试将 double 转换为浮点指针,但我不知道正确的方法。

Here's my code这是我的代码

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

And I get the following result.我得到以下结果。

RESULT : 0
Program ended with exit code: 0

How do I properly cast double to float pointer?如何正确地将 double 转换为浮点指针?

ADD : The result I expect to get is 20添加:我期望得到的结果是 20

Consider:考虑:

#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] );
}

This, at least on my machine, gives the following output:至少在我的机器上,这给出了以下输出:

0 0 0 0 0 0 24 40

Explanation:解释:

That is the internal representation of a double with value 10 .那是值为10double的内部表示。

By casting the double * to float * , you are only looking at the first four bytes of this -- 0 0 0 0 .通过将double *float * ,您只查看它的前四个字节 - 0 0 0 0 Do you see why you are getting a 0 output when you dereference the pointer?当您取消引用指针时,您是否明白为什么会得到0输出?

(Aside from, as others have pointed out, the dereferencing of the pointer being undefined behaviour due to breaking strict aliasing.) (除此之外,正如其他人所指出的,由于打破了严格的别名,指针的取消引用是未定义的行为。)

Solution:解决方法:

What you probably want is to cast the value of d :您可能想要的是转换d

static_cast<float>(d);

You can then store that value in an object of the correct type:然后,您可以将该值存储在正确类型的对象中:

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

Your code for casting the pointer is correct.您用于投射指针的代码是正确的。

The mistake is *f , which causes undefined behaviour by violating the strict aliasing rule.错误是*f ,它通过违反严格的别名规则导致未定义的行为。 You can not read or write through a pointer that has the wrong type for the object it points to.您不能通过指针读取或写入其指向的对象类型错误的指针。 (with a small list of exceptions). (有一小部分例外情况)。

The behaviour is undefined : the language offers no way of doing this.行为未定义:语言没有提供这样做的方法。 For example, sizeof(float*) does not have to be the same as sizeof(double*) .例如, sizeof(float*)不必与sizeof(double*) C++ aims to maximise flexibility. C++ 旨在最大限度地提高灵活性。

You are allowed to cast the address of a double to a const unsigned char* pointer and read the memory that way.您可以将double的地址转换为const unsigned char*指针并以这种方式读取内存。

Otherwise you need to resort to assembly, where at the CPU level, the distinction between a pointer to a type and an integral type is considerably blurred.否则,您需要求助于汇编,在 CPU 级别,指向类型的指针和整数类型之间的区别相当模糊。

If you want to convert a double to a float , then write如果要将double转换float ,请编写

double d = 10; float f = d;

What you want to do is a narrowing static_cast :您想要做的是缩小static_cast

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

The use of reinterpret_cast will fail, because it will not issue the compiler to change the bitwise representation of a double to that one of a float .使用reinterpret_cast将失败,因为它不会发出编译器将double的按位表示更改为float的按位表示。 It literally will reinterpret the double value as a float, yielding weird and undefined results as the representations differ.从字面上看,它会将 double 值重新解释为浮点数,随着表示形式的不同,会产生奇怪且未定义的结果。 static_cast on the other side will take care for you that the representations are adjusted correctly, possibly truncating the least significant bits if necessary.另一边的static_cast会照顾你正确调整表示,如有必要,可能会截断最低有效位。 After this, you can safely use the address of the float variable and access the value with a pointer.在此之后,您可以安全地使用浮点变量的地址并使用指针访问该值。

The behavior you want can be implemented in C++.您想要的行为可以在 C++ 中实现。 Not via a raw pointer, though, but C++ allows user-defined types.虽然不是通过原始指针,但 C++ 允许用户定义类型。

class double_as_float {
  double& d;
public:
  double_as_float(double& d) : d(d) { }
  float operator*() const { return static_cast<float>(d); }
};

Usage:用法:

#include <iostream>
int main() {

    double d = 10;

    double_as_float f { d };
    d = 20;

    std::cout << "RESULT : " << *f << std::endl;
    return 0;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM