fix(apiquery): format float32 query values at float32 precision - #862
fix(apiquery): format float32 query values at float32 precision#862latent-9 wants to merge 1 commit into
Conversation
The query encoder shared a single case between Float32 and Float64 and formatted both with bitSize 64, so a float32 like 43.76 was serialized as 43.7599983215332 instead of 43.76. The apijson and apiform encoders in this repo already split the two cases; mirror them here. Update the test expectations that had baked in the noisy output.
sylvesterkaczmarek
left a comment
There was a problem hiding this comment.
I checked the reflect/formatting semantics here against the sibling encoders. reflect.Value.Float() necessarily returns a float64, but passing bitSize=32 to strconv.FormatFloat tells the formatter to round to the shortest decimal representation that round-trips to the original float32 value. That is the missing distinction in the current query encoder; the float64 path remains unchanged.
This also makes query serialization consistent with internal/apijson and internal/apiform, which already split Float32 and Float64 and use 32-bit formatting for the former. The updated primitive, nested-slice, repeat, and pointer expectations all flow through the same primitive encoder, so the change is exercised in the main container shapes rather than only one scalar case.
I don't see a blocking compatibility issue in the current change.
What
The query encoder shared a single case between
reflect.Float32andreflect.Float64and formatted both with bitSize 64.Why
strconv.FormatFloat(v.Float(), 'f', -1, 64)produces the shortest representation that round-trips as a float64. For a float32 like43.76that yields43.7599983215332, so every float32 query parameter went out with float64 noise digits. The sibling encoders in this repo already handle the two kinds separately —internal/apijson/encoder.goandinternal/apiform/encoder.goboth format Float32 at bitSize 32.Change
Split the case and format Float32 at bitSize 32, matching the other encoders. Two test expectations had the noisy output baked in (
e=43.7599983215332for inputfloat32(43.76)) and are updated to the shortest form; servers parsing the value as a float see an identical number either way, but the wire bytes now match what the same SDK emits through its JSON and form encoders.