4 ms·
> My go-to example in C++ is examining a floating-point number as an integer Which is something that hardly makes any sense and most professional will never ne
by pif 3y ago
> My go-to example in C++ is examining a floating-point number as an integer
Which is something that hardly makes any sense and most professional will never need in their entire career.
- agalunar 3y agoIt depends on what you do! The reason I use this as my go-to example is that I came across the incorrect use of reinterpret_cast for this exact purpose in a previous job (which was firmware-adjacent). edit: are you also expressing disagreement with the claim that few C++ programs are correct (and the implied claim that this is because many people's first-guess approaches are actually incorrect), or just saying that you think this is a bad example of the language being complex or misleading?
- vbezhenar 3y agoSerialization of floating point number makes some sense. Even if you can't reliably read it on other machine, reading it on the same machine should be possible.
- yvdriess 3y agoYes, being able to fwrite() dump floats to binaries is invaluable when working with large datasets. It's common to see binary 'cache' file being created for ASCII inputs (e.g. CSV) when there is any chance of it being fed repeatedly.
- pif 3y ago> fwrite() dump floats to binaries That requires a cast from float* to void*. Reading the floating point number as an integer is not necessary.
- yvdriess 3y agoAFAIK the underlying mechanism and undefined behaviour is the same.
- pif 3y agoNo, it isn't! Casting any object pointer to (and from) void* or char* is guaranteed to work, while float to integer incurs in the undefined behaviour curse.
- yvdriess 3y agoDo I understand you right that for (int i=0; i<4; i++) buf[i] = ((char*)&my_float)[i]; is not undefined behavior? But that for (int i=0; i<4; i++) buf[i] = ((char*)(int32_t*)&my_float)[i]; is undefined?
- pif 3y agoI'm not sure 100%, but your second example does not imply UB. UB is caused by the act of accessing an object via a pointer of the wrong type, but just casting a pointer as you do should not be a problem. On the other side, this would incur UB: int32_t my_int = *((int32_t*)&my_float);
- pif 3y agoSerialization of floating point number makes a lot of sense. But you don't need to read it as an integer.
- 0xf00ff00f 3y agoWhat if you need to do an endianness conversion?
- pif 3y agoIn that case, you need a cast from float* to char*, which is guaranteed to work. There is no sane reason to want to access a float as an integer.
- gpderetta 3y agoI'll just leave this here: https://en.wikipedia.org/wiki/Fast_inverse_square_root https://en.wikipedia.org/wiki/Fast_inverse_square_root
- CyberDildonics 3y agoThey said sane reason and that most programmers would never need to do it. I don't think the magic inverse square root contradicts that.
- pif 3y agoI stand corrected: there is one very good reason to want to treat a float like an integer. But if you can come up with such a solution, you are definitely not one to stop at their first guess, and you'll double-check the standard before the final commit.
- gpderetta 3y agoOk, what about: https://leonardschuetz.ch/blog/nan-boxing/ https://leonardschuetz.ch/blog/nan-boxing/
- tialaramex 3y agoIf you are interested in the actual bits, then that's what this is. Hence in Rust the method on f32 and f64 to do this is named "to_bits"
- pif 3y agoNo, sorry, you are wrong. If you are interested in the actual bits, char* is the way to go.
- tialaramex 3y agoThat's bytes, if you want bytes you need to specify what order you think the bytes are in, Rust's to_be_bytes, to_ne_bytes and to_le_bytes gives you bytes (in Big, Network, or Little endian)
- pif 3y agoI'm not sure that I understand your point. Actually, I wonder if you do ;-)
- tialaramex 3y agoRust provides methods to get your f32 (a 32-bit IEEE floating point number) or f64 (the 64-bit one) as, appropriately, a u32 or u64. Rust calls these methods to_bits because that's what you get. Conveniently Rust doesn't need to care about byte order for these operations because no extant computer makes a different choice for its integer and float representations. Good. You insisted you want char *, by which I understood you meant bytes. Rust can do that too, but now you need to care about byte order. Seeing another answer in this sub-thread I realise you actually meant you wanted a string which is doubly hilarious in a C++ thread. The char * is a pointer to a byte, C++ has actual strings (and, these days, even a passable fat pointer style string reference called std::string_view) and they're different.
- anonymoushn 3y agoIt seems reasonable to pass around 32 bits in a u32 or 64 bits in a u64 rather than using arrays.
- anonymoushn 3y agoHere's one reason you might want to do this https://stackoverflow.com/questions/53882855/simple-explanation-of-the-ankerl-fast-exponent-algorithm https://stackoverflow.com/questions/53882855/simple-explanat...