How do I modify bits of float/double without undefined behavior?
Clash Royale CLAN TAG#URR8PPP
How do I modify bits of float/double without undefined behavior?
I want to set/clear bits of a float and double in C++ and print out the result. I'm positive long long bits = *(long long*)&doubleVar;
invokes undefined behavior. I'm not sure if putting it in a union is correct either. How do I get/set bits of a float and double in C++ without causing undefined behavior?
long long bits = *(long long*)&doubleVar;
char* pChar = reinterpret_cast< char* >(&doubleVar);
reinterpret_cast
@P0W I think I heard it's only allowed to convert a base type to it's parent and convert an int to pointer
– user10206090
Aug 10 at 3:15
2 Answers
2
To avoid undefined behavior you need to use memcpy()
A simple way to do this is using the proposed template std::bit_cast<to_type>(from_type from)
memcpy()
std::bit_cast<to_type>(from_type from)
You can get the template that wraps this operation (it's only proposed) in https://en.cppreference.com/w/cpp/numeric/bit_cast and is simple to use:
double pun_me=3.0;
std::uint64_t ui64=my_namespace::bit_cast<uint64_t>(pun_me);
It's a good idea to put it in a separate namespace so you don't get conflicts when/if it comes out in C++20. You can them modify whatever you wish and convert it back.
I'll upvote when I have the rep
– user10206090
Aug 10 at 3:21
You can use unsigned char *
for that, that's the simplest yet standard conformant way, if you need to modify some of the bits of an existing float
/double
. See:
unsigned char *
float
double
float a = 1.0f;
unsigned char *x = reinterpret_cast<unsigned char *>(&a);
x[3] ^= 0x80; // let's change sign of a (assuming IEEE-754, and little-endian, 8-bit chars)
Doing this with memcpy
or bit_cast
is more complex.
memcpy
bit_cast
By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.
char* pChar = reinterpret_cast< char* >(&doubleVar);
But read details about usingreinterpret_cast
and this construct.– P0W
Aug 10 at 2:25