4 ms·
> Note that textual numbers are surprisingly complex to handle, so any formats with significant number uses should just use binary. Especially true of floats!
by mort96 1y ago
> Note that textual numbers are surprisingly complex to handle, so any formats with significant number uses should just use binary.
Especially true of floats!
With binary formats, it's usually enough to only support machines whose floating point representation conforms to IEEE 754, which means you can just memcpy a float variable to or from the file (maybe with some endianness conversion). But writing a floating point parser and serializer which correctly round-trips all floats and where the parser guarantees that it parses to the nearest possible float... That's incredibly tricky.
What I've sometimes done when I'm writing a parser for textual floats is, I parse the input into separate parts (so the integer part, the floating point part, the exponent part), then serialize those parts into some other format which I already have a parser for. So I may serialize them into a JSON-style number and use a JSON library to parse it if I have that handy, or if I don't, I serialize it into a format that's guaranteed to work with strtod regardless of locale. (The C standard does, surprisingly, quite significantly constrain how locales can affect strtod's number parsing.)
- hyperbolablabla 1y agoCouldn't you just write the hex bytes? That would be unambiguous, and it wouldn't lose precision.
- lifthrasiir 1y agoAt that point human-readability would suffer.
- adgjlsfhk1 1y agoreading hex floats isn't the most intuitive, but isn't that bad.
- analog31 1y agoAn amusing anecdote is that Alan Turing taught himself to read numbers in the internal representation used by the computer, rather than allowing the waste of equipment, time, or labor to translate them.
- mort96 1y agoThat's still a binary format in my eyes, it's not human readable or writable. You've just written the binary format as hex.
- HappMacDonald 1y agoTo me this just sounds like an endianness nightmare waiting to happen.
- dwattttt 1y agoYou do have to be aware of endianness, although it's really not hard to handle it: pick one. Your code always knows what endian the file format is, so it always knows how to read it.
- mort96 1y agoJust add this to your serialiser and deserialiser: if (nativeEndianness != littleEndian) swapBytes(&theFloat); It's really, really not hard in comparison to parsing and serialising textual floats.
- chirsz 1y agoYou can use hexadecimal floating-point literal format that introduced in the C language since C99[^1]. [^1]: https://cppreference.com/w/c/language/floating_constant.html https://cppreference.com/w/c/language/floating_constant.html For example, `0x1.2p3` represents `9.0`.
- analog31 1y agoHere's a weird idea that has occurred me from time to time. What if your editor could recognize a binary float, display it in a readable format, and allow you to edit it, but leave it as binary when the file is saved. Maybe it's discipline-specific, but with the reasonable care in handling floats that most people are taught, I've never had a consequential mishap.
- mort96 1y agoI don't know how you would do that in practice, since every valid sequence of 4 or 8 bytes is a valid float. Maybe you could exclude some of the more unusual NaN representations but it still leaves you with most byte sequences being floats. For example, the ASCII string "Morn", stored as the bytes '0b01001101 0b01101111 0b01110010 0b01101110', could be interpreted as the 32-bit float 0b01101110011100100110111101001101, representing the number 1.8757481691240478e+28. So you couldn't really just have smart "float recognition" built in to an editor as a general feature, you would need some special format which the editor understands which communicates "the following 4 bytes is a single-precision float" or "the following 8-byte is a double-precision float".
- analog31 1y agoGood point. It strikes me that Unicode is already analogous to recognition of multi byte characters. Maybe something along similar lines would work.