compare Fmt Sprintf with an alternative
Fast recall
Quick revision
Core answer
Practical understanding of Fmt Sprintf.
Repeating a definition without saying when to use it.
Give one trade-off and say how you would test it.
Interview-ready guide
Interview answer
The fixed-decimal form is %.Nf:
fmt.Sprintf("%.2f", 3.14159) // "3.14"
fmt.Sprintf("%.0f", 2.7) // "3" — rounds
fmt.Sprintf("%8.2f", 3.14159) // " 3.14" — width 8, right-alignedThe scientific form is %e ("3.14e+00"), the shortest-round-trip is %g (picks f or e by magnitude — what fmt.Println uses by default).
The representation surprise every float formatter must know: binary floating point can't exactly represent most decimal fractions — 0.1 is stored as 0.1000000000000000055511... The DEFAULT rendering shows this: fmt.Println(0.1) prints 0.1 (Go's %g picks the shortest form that round-trips — reading it back gives the same bits), but naive %.20f exposes the truth: 0.10000000000000000555.
The consequences: %.2f is a DISPLAY format (rounding for humans); comparing formatted strings for float equality is wrong (rounds differently at boundaries); and money — the classic case — should be integer cents (int64), formatted by dividing at display time. The rounding Go uses for %.Nf is correct decimal rounding of the binary value — but the value itself carries the representation error.
For exact decimal arithmetic: math/big.Float or a decimal library (or the int-cents pattern). For display: %.Nf with the knowledge that it's display.
compare Fmt Sprintf with an alternative
Direct Answer
%.2f for fixed decimals: fmt.Sprintf("%.2f", 3.14159) → "3.14". strconv.FormatFloat for the fast path. Beware: binary floats can't represent 0.1 exactly — format for display, never compare formatted output for equality.
Deep Dive & Architecture
Why %g prints 0.1 as '0.1' — the shortest-round-trip algorithm: Go's float formatting tries successively shorter decimal representations until it finds one that, PARSED BACK, yields the identical float64 bits. 0.1's nearest representable double is 0.1000000000000000055511151231257827... — but '0.1' parses to exactly that double, so '0.1' wins. This is Ryu-style shortest-printing (modern Go uses a variant) — the guarantee: the printed form round-trips exactly, so logging a float and parsing the log NEVER corrupts the value.
%.Nf's mechanics vs %g: %.Nf is positional decimal formatting with rounding at the Nth place (correct half-away-from-zero on the binary value's decimal expansion). %g adapts (fixed or scientific, by exponent range, defaulting to shortest). %e is always scientific. The three cover the display space: fixed (%f), scientific (%e), adaptive-short (%g).
The money pattern, fully: float amounts accumulate error (0.1 + 0.2 = 0.30000000000000004 — the famous demonstration), so amounts store as int64 cents/units; display divides: fmt.Sprintf("%d.%02d", cents/100, cents%100) — integer math all the way, formatting only at the edge. Interviewers probe this as 'how do you handle money in Go' — the answer is never 'floats with %.2f'; it's int cents + the divide-at-display idiom, with the float path reserved for physical/scientific quantities where the representation error is smaller than measurement error.
Common Mistakes & Pitfalls
Repeating a definition without saying when to use it.
Check your understanding
Answer these without looking back at the article.
- What is Fmt Sprintf, and when would you use it?
- When would you use Fmt Sprintf in a real project?
- What is a common mistake when using Fmt Sprintf?
Looking for a structured roadmap?
Every module on this page is also part of the full Java backend interview track.