Question
How can you convert a float64 to an int in Go?
I know the strconv package is useful for converting values to and from strings, but not for converting directly between numeric types when no string is involved.
I also know I could use fmt.Sprintf() to turn the number into a string first and then use strconv to parse it, but that feels unnecessarily clumsy. Is there a simpler and more idiomatic way to do this in Go?
Short Answer
By the end of this page, you will understand how numeric type conversion works in Go, especially how to convert a float64 to an int using Go's built-in type conversion syntax. You will also learn what happens to the decimal part, when rounding is needed, common mistakes to avoid, and how this appears in real Go programs.
Concept
In Go, converting between numeric types does not require strconv or string formatting. Instead, Go provides explicit type conversion.
To convert a float64 to an int, you write:
i := int(f)
Here, f is a float64, and int(f) tells Go to create a new value of type int from f.
This matters because Go is a strongly typed language. It does not automatically convert between numeric types for you. Even though both float64 and int represent numbers, they are different types with different behavior:
float64can store decimal valuesintstores whole numbers only
When you convert from float64 to int, Go discards the fractional part. This is called truncation.
For example:
fmt.Println(int(3.9)) // 3
fmt.Println(int(3.1)) // 3
fmt.Println(int(-3.9)) // -3
Notice that Go does not round to the nearest whole number during conversion. It simply removes everything after the decimal point.
If you actually want rounding behavior, you should use the math package first, then convert the result.
rounded := int(math.Round(3.9)) // 4
So the core idea is:
- Use type conversion for numeric types
- Use
strconvonly when working with strings - Be aware that
float64 -> inttruncates, not rounds
Mental Model
Think of a float64 as a measuring cup that can hold partial amounts, like 3.7 cups of water.
An int is like a box that only accepts whole items. If you pour 3.7 cups into a container that only stores whole numbers, the .7 part does not fit, so it gets dropped.
That is what Go does with:
int(3.7)
It keeps the whole-number part and throws away the fractional part.
If you want the nearest whole item instead, you must round first before putting it into the integer box.
Syntax and Examples
The basic syntax is:
intValue := int(floatValue)
Example 1: Simple conversion
package main
import "fmt"
func main() {
f := 12.75
i := int(f)
fmt.Println(f) // 12.75
fmt.Println(i) // 12
}
i becomes 12 because the decimal part .75 is removed.
Example 2: Negative numbers
package main
import "fmt"
func main() {
f := -8.99
i := int(f)
fmt.Println(i) // -8
}
This often surprises beginners. The result is -8, not -9, because conversion truncates toward zero.
Example 3: Round before converting
package main
import (
"fmt"
"math"
)
func main() {
f := 12.75
i := int(math.Round(f))
fmt.Println(i) // 13
}
Use math.Round() when you want normal rounding instead of truncation.
Example 4: Floor and ceil
package main
import (
"fmt"
"math"
)
func main() {
f := 12.75
fmt.Println(int(math.Floor(f))) // 12
fmt.Println(int(math.Ceil(f))) // 13
}
These are useful when you need predictable rounding direction.
Step by Step Execution
Consider this example:
package main
import "fmt"
func main() {
f := 5.99
i := int(f)
fmt.Println(i)
}
Step by step:
-
f := 5.99- A variable
fis created. - Its type is inferred as
float64. - Its value is
5.99.
- A variable
-
i := int(f)- Go converts
ffromfloat64toint. - Since
intcannot store decimals, the fractional part.99is discarded. ibecomes5.
- Go converts
-
fmt.Println(i)- The program prints
5.
- The program prints
Another trace with a negative number
f := -5.99
i := int(f)
What happens:
- Start with
-5.99 - Remove the fractional part
- Result:
-5
This is truncation toward zero, not mathematical floor.
Real World Use Cases
Converting float64 to int is common when a program receives decimal values but later needs whole-number values.
Common situations
-
User input processing
- A form or API sends a decimal value like
42.0 - Your code needs an integer for indexing, counting, or storage
- A form or API sends a decimal value like
-
Working with measurements
- A calculation returns
15.8 - You only want the whole-unit portion, such as pixels, items, or seconds
- A calculation returns
-
UI and graphics code
- Layout calculations may use floating-point math
- Screen coordinates often need integer values
-
Data processing
- A CSV or JSON file contains decimal numbers
- You want to convert them into integer counters or IDs after validation
-
Time and rate calculations
- You compute averages or durations as floats
- Later you need an integer number of seconds, retries, or batches
Example: pixels in a layout
width := 199.8
pixelWidth := int(width)
Example: API data cleanup
price := 49.99
wholePart := int(price)
Be careful: in some cases, dropping decimals is correct, but in others you may need rounding instead.
Real Codebase Usage
In real Go projects, developers usually use direct type conversion in small, focused places rather than building string-based conversions.
Common patterns
Validation before conversion
If the float must be within a safe range or must not contain a fractional part, validate first.
package main
import (
"errors"
"math"
)
func floatToIntExact(f float64) (int, error) {
if math.Trunc(f) != f {
return 0, errors.New("value has a fractional part")
}
return int(f), nil
}
This pattern is useful when decimals should be rejected instead of silently removed.
Rounding before storing
count := int(math.Round(result))
Used when a computed value should become the nearest whole number.
Guard clauses
func retries(delay float64) int {
if delay <= 0 {
return 0
}
return int(delay)
}
This keeps conversion logic simple and safe.
Conversion near boundaries
In real codebases, developers often convert as late as possible:
- keep calculations in
float64 - convert to
intonly when needed
This helps avoid losing precision too early.
Parsing and conversion are separate steps
If input comes from text, developers typically do this:
f, err := strconv.ParseFloat(input, 64)
if err != nil {
return err
}
i := int(f)
strconv handles the string parsing. The numeric conversion is still done with int(f).
Common Mistakes
1. Using strconv for numeric-to-numeric conversion
Broken idea:
s := fmt.Sprintf("%f", f)
i, _ := strconv.Atoi(s)
Why it is a mistake:
- unnecessary
- inefficient
- harder to read
Atoiexpects an integer string like"12", not"12.750000"
Correct approach:
i := int(f)
2. Expecting rounding instead of truncation
Broken assumption:
f := 9.9
fmt.Println(int(f)) // expected 10, actually 9
Fix:
i := int(math.Round(f))
3. Forgetting negative numbers truncate toward zero
Broken assumption:
f := -4.8
fmt.Println(int(f)) // expected -5, actually -4
Fix:
- Use
math.Floor()if you want-5 - Use
math.Round()if you want nearest rounding
4. Converting too early
Broken pattern:
f := 5.8
x := int(f)
y := x * 2
This loses precision early.
Better:
f := 5.8
y := int(f * 2)
Now the multiplication happens before the precision is dropped.
5. Ignoring range issues
Very large floating-point values may not fit safely into int, depending on the system.
Safer approach:
- validate the expected range
- avoid converting values you have not checked
6. Assuming int has the same size everywhere
In Go, int is implementation-dependent.
If you need a fixed size, use types like:
int32int64
Example:
var f float64 = 42.3
var x int64 = int64(f)
Comparisons
| Concept | Purpose | Example | Notes |
|---|---|---|---|
int(f) | Convert float to integer | int(3.9) → 3 | Truncates decimal part |
math.Round(f) then int(...) | Round to nearest whole number | int(math.Round(3.9)) → 4 | Best when normal rounding is needed |
math.Floor(f) then int(...) | Always round down | int(math.Floor(3.9)) → 3 | For negatives, floor goes to smaller value |
math.Ceil(f) then int(...) | Always round up | int(math.Ceil(3.1)) → 4 | Useful for capacity calculations |
strconv.ParseFloat() | Convert string to float | strconv.ParseFloat("3.14", 64) | Used for text input |
strconv.Atoi() | Convert string to int | strconv.Atoi("42") | Only for integer strings |
int() vs strconv
- Use
int()when you already have a numeric value. - Use
strconvwhen you are converting between strings and numeric values.
int() vs rounding functions
int(f)removes decimalsmath.Round(f)chooses the nearest whole numbermath.Floor(f)always goes downwardmath.Ceil(f)always goes upward
Cheat Sheet
// float64 to int
i := int(f)
Key rule
float64 -> inttruncates the fractional part
Examples
int(3.9) // 3
int(3.1) // 3
int(-3.9) // -3
Round first if needed
int(math.Round(3.9)) // 4
int(math.Floor(3.9)) // 3
int(math.Ceil(3.1)) // 4
When to use what
- Use
int(f)for direct numeric conversion - Use
strconv.ParseFloat()for strings like"3.14" - Use
strconv.Atoi()for strings like"42"
Important reminders
- Go does not auto-convert numeric types
int(f)is explicit conversion- Conversion is not the same as parsing
- Converting too early can lose precision
intsize can vary by platform
FAQ
How do I convert a float64 to an int in Go?
Use explicit type conversion:
i := int(f)
Does Go round when converting float64 to int?
No. Go truncates the fractional part.
int(7.9) // 7
How do I round a float64 before converting in Go?
Use the math package:
i := int(math.Round(f))
Why should I not use strconv for this?
Because strconv is for converting between strings and numeric values. If you already have a float64, direct type conversion is simpler and idiomatic.
What happens with negative floats?
Go truncates toward zero.
int(-4.9) // -4
Can converting float64 to int lose information?
Yes. The decimal part is discarded, and very large values may also create problems if they do not fit cleanly into int.
Should I use int, int32, or int64?
Use int for general-purpose counting and indexing. Use int32 or int64 when you need a specific size.
Mini Project
Description
Build a small Go program that processes decimal scores and converts them into whole-number values in different ways. This project demonstrates direct type conversion, truncation, and rounding so you can see when each approach is appropriate.
Goal
Create a program that takes several float64 values and prints their truncated, rounded, floored, and ceiled integer versions.
Requirements
- Define a slice of
float64values with positive and negative decimals. - Loop through each value and convert it using
int(),math.Round(),math.Floor(), andmath.Ceil(). - Print the original value and each converted result clearly.
- Keep the program runnable as a single Go file.
Keep learning
Related questions
Are Go Maps Passed by Value or Reference?
Learn Go map parameter and return semantics: maps are passed by value, while copies share underlying data. Know when map pointers are useful.
Authentication for Go REST APIs: Sessions, Tokens, and Middleware
Learn practical authentication patterns for Go REST APIs, including password hashing, server sessions, bearer tokens, middleware, and security rules.
Automatic Build Versioning in Go: Embed Incrementing Build Numbers
Learn how to add automatic build versioning in Go using linker flags, build metadata, CI counters, and Git-based version values.