You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Float#to_s diverges from MRI: missing mantissa fraction, and the wrong fixed/exponential threshold #619
Float#to_s/#inspect (internal/object/object.go, func (f Float) ToS) formats with Go's strconv.FormatFloat(v, 'g', -1, 64) and then appends .0 only when the result contains no ., e or E. That diverges from MRI in two independent ways.
1. The mantissa loses its fraction in exponential form
source
MRI 4.0.5
rbgo
1e-06
1.0e-06
1e-06
1e+20
1.0e+20
1e+20
-1e-06
-1.0e-06
-1e-06
5e-324
5.0e-324
5e-324
Ruby always shows a fractional digit; the .0 is appended only in fixed form today, so 1e-06 keeps a bare mantissa.
2. The fixed/exponential threshold is Go's, not Ruby's
Go's %g switches to exponential by comparing the exponent against the number of significant digits. MRI's flo_to_s (numeric.c) switches on where the decimal point falls: exponential iff decpt < -3 || decpt > DBL_DIG (15).
Measured against ruby 4.0.5, the boundaries are exactly:
The visible symptom is 1e6: MRI prints 1000000.0, rbgo prints 1e+06.
Suggested shape
Take the shortest round-tripping digits from strconv.FormatFloat(v, 'e', -1, 64), derive decpt from its exponent, then choose fixed ('f', -1) or exponential by MRI's rule, and in exponential form ensure the mantissa carries at least one fractional digit. Go's exponent padding already matches (e+06, e-05, e+100, e-323).
Why it is worth a dedicated pass
The blast radius is wide — every pinned test and spec that prints a float — so it wants the full go test ./... gate and probably some pinned-value updates in the same change. It was found while landing #617 (core/process) and deliberately left out of that PR, which owns unrelated files.
Activity