Question
Kotlin has a useful feature called string templates:
val i = 10
val s = "i = $i" // evaluates to "i = 10"
Can string templates also apply formatting?
For example, how can a Double be formatted inside a Kotlin string template so that it shows a fixed number of digits after the decimal point?
val pi = 3.14159265358979323
val s = "pi = $pi" // How can this become "pi = 3.14"?
Short Answer
By the end of this page, you will understand the difference between string templates and string formatting in Kotlin, how to format numbers like Double values, and the most common ways developers produce output such as 3.14 instead of a long decimal value.
Concept
Kotlin string templates let you insert values directly into strings using $variable or ${expression}. They are great for readability and convenience:
val name = "Ada"
println("Hello, $name")
However, string templates do not provide built-in formatting syntax like “show 2 decimal places” directly inside $value.
That means this does not exist as template-specific syntax:
// Not valid Kotlin formatting syntax
val s = "pi = $pi:2f"
Instead, you usually do one of these:
- Format the value first, then place it in the template.
- Use an expression inside
${...}that returns a formatted string. - Use formatting functions such as
String.format().
For numeric formatting, Kotlin commonly relies on Java's formatting tools on the JVM, such as:
val pi = 3.141592653589793
val s = "pi = ${"%.2f".format(pi)}"
This produces:
pi = 3.14
Why this matters:
- Raw numbers may show too many decimal places.
- User-facing output often needs clean formatting.
- Reports, prices, measurements, and UI text usually require controlled precision.
So the key idea is:
- String templates insert values
- Formatting functions shape values before insertion
Mental Model
Think of a string template as a label printer.
$pimeans: “print whatever is currently inpi.”- It does not mean: “decide how many decimal places to show.”
If you want prettier output, you must prepare the value before printing the label.
So instead of this:
- “Print the raw number”
You do this:
- “First convert the number into a nicely formatted string”
- “Then insert that string into the template”
In short:
- Template = insertion
- Format = conversion before insertion
Syntax and Examples
Basic string template
val pi = 3.141592653589793
println("pi = $pi")
Output:
pi = 3.141592653589793
Format to 2 decimal places
A common Kotlin approach is:
val pi = 3.141592653589793
val s = "pi = ${"%.2f".format(pi)}"
println(s)
Output:
pi = 3.14
What "%.2f" means
%f= floating-point number.2= show 2 digits after the decimal point%.2f= format as a decimal with 2 digits after the decimal
Using String.format
val pi = 3.141592653589793
val s = String.format("pi = %.2f", pi)
println(s)
Output:
pi = 3.14
Formatting inside a template expression
val price = 12.5
println("Price: ${"%.2f".format(price)}")
Output:
Price: 12.50
Formatting more than one value
val width = 5.6789
val height = 9.1234
println("Size: ${"%.1f".format(width)} x ${"%.1f".format(height)}")
Output:
Size: 5.7 x 9.1
Step by Step Execution
Consider this example:
val pi = 3.141592653589793
val formatted = "%.2f".format(pi)
val result = "pi = $formatted"
println(result)
Step by step:
-
val pi = 3.141592653589793- A
Doublevalue is stored inpi.
- A
-
val formatted = "%.2f".format(pi)- The format pattern
%.2fis applied topi. - The result is the string
"3.14".
- The format pattern
-
val result = "pi = $formatted"- Kotlin inserts the already formatted string into the template.
resultbecomes"pi = 3.14".
-
println(result)- The final text is printed.
Final output:
pi = 3.14
You can also do it in one line:
println("pi = ${"%.2f".format(pi)}")
That works because ${...} allows any expression that returns a value.
Real World Use Cases
Formatting numbers inside strings is common in real programs.
Prices and money
val total = 19.9
println("Total: ${"%.2f".format(total)}")
Useful for receipts, checkout pages, and invoices.
Measurements
val temperature = 21.678
println("Temperature: ${"%.1f".format(temperature)}°C")
Useful in dashboards, sensor apps, and weather displays.
Reports and analytics
val conversionRate = 0.45678
println("Conversion rate: ${"%.2f".format(conversionRate * 100)}%")
Useful for logs, summaries, and business reports.
Scientific or engineering output
val voltage = 3.14159
println("Voltage: ${"%.3f".format(voltage)} V")
Useful when controlled precision matters.
Logging readable values
val loadTime = 1.234567
println("Load time: ${"%.2f".format(loadTime)} seconds")
Useful when raw floating-point output is too noisy.
Real Codebase Usage
In real projects, developers rarely sprinkle raw numeric values directly into user-facing strings. Instead, they usually format values close to the presentation layer.
Common patterns
Format before display
fun formatPrice(price: Double): String {
return "%.2f".format(price)
}
Then use it:
println("Total: ${formatPrice(12.5)}")
This keeps formatting logic reusable.
Guard clauses before formatting
fun formatScore(score: Double?): String {
if (score == null) return "N/A"
return "%.1f".format(score)
}
Useful when values may be missing.
Validation before output
fun formatPercentage(value: Double): String {
require(value >= 0) { "Percentage cannot be negative" }
return "%.2f%%".format(value)
}
This prevents invalid display values.
Centralized formatting helpers
In larger codebases, formatting is often placed in helper functions or formatter classes so the app uses consistent decimal places everywhere.
object NumberFormatter {
fun twoDecimals(value: Double): String = "%.2f".format(value)
}
Early return for special cases
fun formatDistance(distance: Double): String {
if (distance == 0.0) return "0 m"
return "%.2f m".format(distance)
}
This makes edge cases explicit and easy to read.
Common Mistakes
1. Expecting formatting syntax inside $value
Broken idea:
val pi = 3.14159
val s = "pi = $pi%.2f"
Why it is wrong:
- Kotlin templates do not understand formatting directives attached to
$pi.
Correct approach:
val s = "pi = ${"%.2f".format(pi)}"
2. Forgetting ${...} for expressions
Broken code:
val pi = 3.14159
val s = "pi = "%.2f".format(pi)
Why it is wrong:
- Inside a string template, complex expressions must go inside
${...}.
Correct code:
val s = "pi = ${"%.2f".format(pi)}"
3. Confusing rounding with truncation
val pi = 3.14159
println("%.2f".format(pi))
This gives:
3.14
Formatting usually rounds the number to the requested precision. It does not simply cut off digits in all cases.
4. Using raw Double output for UI text
val total = 12.0
println("Total: $total")
This may display 12.0 when you want 12.00.
Better:
println("Total: ${"%.2f".format(total)}")
5. Mixing locale-sensitive output without thinking
Depending on environment and locale, decimal separators can vary when formatting. In some contexts, you may need to specify a locale explicitly.
Example:
val s = java.lang.String.format(java.util.Locale.US, "%.2f", 3.14)
Use this when output must always use . as the decimal separator.
Comparisons
| Approach | What it does | Best for | Example |
|---|---|---|---|
$value | Inserts raw value | Quick debugging or simple strings | "pi = $pi" |
${expression} | Inserts result of an expression | Formatting or calculations inside templates | "pi = ${"%.2f".format(pi)}" |
"%.2f".format(value) | Formats one value into a string | Simple numeric formatting | "%.2f".format(pi) |
String.format(...) | Formats a whole string with placeholders | Multiple formatted values in one call | String.format("pi = %.2f", pi) |
String templates vs string formatting
| Feature | String template | String formatting |
|---|---|---|
| Purpose | Insert values into strings | Control how values appear |
| Syntax | $name, ${expression} | "%.2f".format(value) |
| Handles decimal places directly | No | Yes |
| Good for readability | Yes | Yes, especially for numeric output |
When to use which
- Use string templates when you just need to insert values.
- Use formatting when appearance matters.
- Combine both when you want readable code:
println("pi = ${"%.2f".format(pi)}")
Cheat Sheet
Quick reference
Insert a raw value
val x = 10
println("x = $x")
Insert an expression
val x = 10
println("double = ${x * 2}")
Format a Double to 2 decimal places
val pi = 3.14159
println("%.2f".format(pi))
Format inside a string template
println("pi = ${"%.2f".format(pi)}")
Format a whole string
val s = String.format("pi = %.2f", pi)
Useful patterns
%.1f→ 1 digit after decimal%.2f→ 2 digits after decimal%.3f→ 3 digits after decimal%d→ integer%s→ string
Rules to remember
$variableinserts the value as-is.${...}is required for expressions.- String templates do not have built-in decimal formatting syntax.
- Use
.format(...)orString.format(...)for formatted output.
Common answer to the original problem
val pi = 3.141592653589793
val s = "pi = ${"%.2f".format(pi)}"
FAQ
How do I format a Double to 2 decimal places in Kotlin?
Use:
"%.2f".format(value)
Example:
val pi = 3.14159
println("%.2f".format(pi)) // 3.14
Can Kotlin string templates format numbers directly?
No. String templates insert values, but they do not provide built-in numeric formatting rules like decimal precision.
What is the difference between $value and ${expression} in Kotlin?
$valueinserts a variable directly.${expression}evaluates an expression and inserts its result.
How do I format a number inside a Kotlin string template?
Use a formatting expression inside ${...}:
println("pi = ${"%.2f".format(pi)}")
Does %.2f round the number?
Yes, it formats the number to 2 decimal places using rounding.
Should I use String.format() or .format() in Kotlin?
Both are useful. .format() is concise for single values, while String.format() can be clearer when formatting a full string with multiple placeholders.
Why does my formatted number sometimes use a comma instead of a dot?
Formatting can be locale-sensitive. If you need a specific decimal separator, specify a locale explicitly.
Mini Project
Description
Build a small Kotlin program that prints a mini receipt. The goal is to practice formatting Double values for display inside strings, which is a common task in command-line apps, reports, and UI text.
Goal
Create a receipt that displays item prices and a final total using exactly 2 decimal places.
Requirements
- Define at least three item prices as
Doublevalues. - Print each item price using exactly 2 decimal places.
- Calculate the total price.
- Print the total using a string template with formatted output.
Keep learning
Related questions
Accessing Kotlin Extension Functions from Java
Learn how Kotlin extension functions are compiled and how to call them correctly from Java with clear examples and common pitfalls.
Add a Maven Repository URL in Gradle Kotlin DSL (build.gradle.kts)
Learn how to add Maven Central and a custom Maven repository URL in Gradle Kotlin DSL using build.gradle.kts syntax.
Allow HTTP and HTTPS in Android 9 Pie with Network Security Configuration
Learn how Android 9 Pie handles cleartext HTTP traffic and how to allow HTTP and HTTPS safely using network security config.