Reputation: 3044
I'm trying to cast double to float pointer but I don't know the proper way to do it.
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?
ADD : The result I expect to get is 20
Upvotes: 5
Views: 12284
Reputation: 70263
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
.
By casting the double *
to float *
, you are only looking at the first four bytes of this -- 0 0 0 0
. Do you see why you are getting a 0
output when you dereference the pointer?
(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
:
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;
Upvotes: 9
Reputation: 179809
The behavior you want can be implemented in C++. Not via a raw pointer, though, but C++ allows user-defined types.
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;
}
Upvotes: 1
Reputation: 234695
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*)
. C++ aims to maximise flexibility.
You are allowed to cast the address of a double
to a const unsigned char*
pointer and read the memory that way.
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.
If you want to convert a double
to a float
, then write
double d = 10; float f = d;
Upvotes: 4
Reputation: 7581
What you want to do is a narrowing 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
. It literally will reinterpret the double value as a float, yielding weird and undefined results as the representations differ. 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. After this, you can safely use the address of the float variable and access the value with a pointer.
Upvotes: 1
Reputation: 141554
Your code for casting the pointer is correct.
The mistake is *f
, which causes undefined behaviour by violating the strict aliasing rule. 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).
Upvotes: 4