-
Notifications
You must be signed in to change notification settings - Fork 1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Integer from floating-point description #67
Comments
I'll work on this for a while. Maybe I'll fix Apple's JSON decoder while I'm at it. |
🪄 ✨ ✨ ✨ ✨ ✨ ✨ ✨ ✨ ✨ ✨ ✨ ✨ ✨ ✨ ✨ ✨ ✨ ✨ ✨ ✨ ✨ ✨ |
So it turns out that you can clamp the exponent to the bounds of Int, if the maximum number of characters is Int.max. But this only works if you normalize the integer, fraction, and exponent parts in a specific way. Otherwise, the saturation may introduce lossy behavior near Int.max character inputs. You'll never actually parse inputs that big, but there's a proper way of doing it with signed same-size integers. I considered using sign-magnitude to get an extra bit of space, but then I thought of the normalization thing. Signed integer buffer sizes save the day again. |
But a sign-magnitude exponent is simpler in practice because applying the normalization bias correctly is nontrivial. |
I want to support JSON, JSON5 and whatever Swift is doing. The JSON ones work, but I just realized that Swift parses this thing: {sign}0x{hex}.{hex}p{sign}{decimal}. I'll totally parse that too, but mixing hex and decimal is rude :( |
Sign and magnitude exponent saturation does not work in the case of 0x{hex}.{hex}p{decimal} since the exponent part respresents a binary multiplier. You need more bits, basically. It might be simpler to just limit the input size to some silly-big-but-small-enough number or settle on a larger exponent type. Hm. |
So, I bascally have a lossless |
It turns out that you can map uppercase letters to lowercase letters, and vice versa, with a bitwise operation (e.g. x | 32). It works because they are offset by a power of two relative to each other in ASCII. This trick turns 3 branches into 2, which makes hexadecimal decoding a few % faster. Note that the uppercase to lowercase transformation is simpler to represent in code, becaue it's easier to set a bit than it is to clear a bit using integer literals. I also reworked the numeral decoding and encoding test suite while I was at it.
Hm. Theres a tricky edge case for integer sizes that aren't multiples of 4. Adding a hexadecimal digit might overflow a significand that is brought back into range by the binary exponent. Remember that |
I've been writing it in Swift proper with thoughts of porting it to this project, but the opposite seems wiser given that I have infrastructure I might want to evolve with the solution. Zzz. At least I found some edge cases that only applies to the former. |
I wonder if the exponent type in BinaryInteger/power(_:) (#53) should be |
I'm sure I'll need to losslessly parse arbitrary floating-point numbers at some point.
The text was updated successfully, but these errors were encountered: