Closed rbjorklin closed 8 months ago
Preserving the original string representation of a float would require keeping it around alongside the float since in general there are many valid representations for the same float. Atdgen is focused on correctness i.e. it's the float→JSON→float roundtrip that matters, not JSON→float→JSON. So, it's unlikely that we can or will add a feature to support this specifically.
Yojson offers a Raw parsing mode and AST that keeps the original literals but I don't see how it could be used to solve this problem simply and conveniently with atdgen. Yojson.Raw
would allow you to change the float literals into whatever literals you want or create a mapping from floats to preferred literals but it would make things slower and non-obvious. Is this feature something you really need, though?
I'm interacting with a financial api endpoint which expects 2 decimals. It does seem to work sending floats but it is unclear to me what what actually happens on the other side. It's probably fine.
If you know you need 2 decimals on all floats and you're worried that something like 1.999999
will be truncated to 1.99
instead of 2.00
, it's a little simpler. You can postprocess the JSON produced by atdgen using Yojson.Raw: parse it, replace all Floatlit nodes, and print the JSON again.
If there are different float nodes with different precision requirements, you'll have to be careful but it's still doable. It's all very hacky, though. I wonder why this API doesn't use ints or maybe strings to represent decimal numbers.
Given atd
's focus on correctness of float -> JSON -> float as previously stated I think the conclusion here is that this works as intended and won't change. I'm okay with that as my wrapping into Bigdecimal.t
with rounding on the unwrapping side should protect me from surprises.
Thanks again for your time @mjambon!
Closing!
I was asked to open a separate issue for this here.
I would like for there to be a way to round-trip numbers and have them come back with the same number of significant figures. I'm not familiar with the
yojson
code base but maybeFloatlit
could be used to achieve this?Example of the current behaviour:
my_type.atd
:my_type_test.ml
:EDIT:
I'm currently using [
Bigdecimal
]() for my numeric functions and what I've got looks something like this:If I could entirely skip using
float
as some kind of intermediate representation that would be good enough for me. I would also be okay parsing it intostring
as long as I can drop the quotes as I'm serializing it back tojson
.