Skip to content

fix(apiquery): format float32 query values at float32 precision - #862

Open
latent-9 wants to merge 1 commit into
openai:mainfrom
latent-9:fix-apiquery-float32-precision
Open

fix(apiquery): format float32 query values at float32 precision#862
latent-9 wants to merge 1 commit into
openai:mainfrom
latent-9:fix-apiquery-float32-precision

Conversation

@latent-9

Copy link
Copy Markdown

What

The query encoder shared a single case between reflect.Float32 and reflect.Float64 and 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 like 43.76 that yields 43.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.go and internal/apiform/encoder.go both 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.7599983215332 for input float32(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.

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.
@latent-9
latent-9 requested a review from a team as a code owner August 26, 2026 05:17

@sylvesterkaczmarek sylvesterkaczmarek left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants