| Tested on | RHEL 10.2 with Go 1.27.0 |
|---|---|
| Package | go 1.27.0 |
| Applies to | Any host with Go 1.20+ installed |
| Privilege | Normal user |
| Scope | float64 to int and int64 conversion: truncation vs rounding with math.Round, RoundToEven, Floor, and Ceil; overflow, NaN, and infinity; int vs int64 width. Does not cover string formatting or full strconv parsing. |
| Related guides | Type casting in Go Convert int to string in Go strconv in Go Golang tutorial Getting started with Go |
Truncate vs round: a bare cast discards the fractional part; rounding helpers choose a different rule before you convert. Pick the row that matches what you need:
| Desired result | Code |
|---|---|
| Discard fractional part | int(x) |
| Fixed 64-bit result | int64(x) |
| Nearest, half away from zero | int(math.Round(x)) |
| Nearest, ties to even | int(math.RoundToEven(x)) |
| Always toward +∞ | int(math.Ceil(x)) |
| Always toward −∞ | int(math.Floor(x)) |
Conversion truncates toward zero—not toward negative infinity:
var pos, neg float64 = 5.9, -5.9
int(pos) // 5
int(neg) // -5Convert float64 to int or int64
A conversion expression is the direct path when truncation is what you want:
package main
import "fmt"
func main() {
var x float64 = 25.36
fmt.Println(int(x)) // 25
var g float64 = -3.9
fmt.Println(int(g), int64(g))
}25
-3 -3Truncation applies to a non-constant floating-point value. A fractional numeric constant cannot be converted directly to an integer—constant conversions must be exactly representable:
// int(25.36) // compile error: cannot convert 25.36 (untyped float constant) to type intThe Go specification distinguishes constant conversions from non-constant numeric conversions. Expressions such as int(1.2) and int(3.14) are illegal constant conversions; non-constant float64 to integer conversions discard the fraction instead. If the value is genuinely a runtime float64, converting it to an integer truncates toward zero. Untyped constants follow stricter compile-time representability rules.
int(x) already truncates toward zero, so int(math.Trunc(x)) is redundant for the cast itself. math.Trunc is useful when you want to drop the fraction but keep a float64 result—for example math.Trunc(-3.9) is -3.0.
int and int64 follow the same truncation rule; only the target width differs. int is 32 or 64 bits depending on the platform. int64 is always 64 bits. Use int for ordinary indexes and slice lengths when the value fits. Use int64 when an API, file format, network protocol, or schema requires a fixed width.
Round before converting
When you need a rounding policy, call math first, then cast. The cast still truncates—but on an integer-valued float64, truncation changes nothing.
Round, RoundToEven, Floor, and Ceil
math.Round picks the nearest integer; ties go away from zero:
math.Round(2.5) // 3
math.Round(-2.5) // -3math.RoundToEven is useful when half-way cases should land on the nearest even integer:
math.RoundToEven(2.5) // 2
math.RoundToEven(3.5) // 4math.Floor and math.Ceil always move toward negative or positive infinity. This table compares the rules on the same inputs (cast results use int(x) after each helper where noted):
| x | int(x) |
Round(x) |
Floor(x) |
Ceil(x) |
|---|---|---|---|---|
| 2.7 | 2 | 3 | 2 | 3 |
| -2.7 | -2 | -3 | -3 | -2 |
For production code, one line is enough once you know the rule—for example n := int(math.Round(score)) when you want nearest-integer scoring.
Handle overflow, NaN, and infinity
The Go specification says that when a non-constant floating-point value cannot be represented by the target integer type, the conversion is allowed but the result value is implementation-dependent. Do not depend on any particular overflow result.
Guard magnitude when values can be extreme. Casting math.MaxFloat64 to int is not portable logic even if your current build prints a fixed sentinel.
For int64—the fixed-width case you can validate reliably—compare against float boundaries before converting. Use x >= 1<<63 as the upper check, not x > float64(math.MaxInt64), because float64 cannot represent math.MaxInt64 exactly; that boundary rounds to 2^63:
const (
minInt64Float float64 = -1 << 63
maxInt64Float float64 = 1 << 63
)
if math.IsNaN(x) || math.IsInf(x, 0) ||
x < minInt64Float || x >= maxInt64Float {
return fmt.Errorf("float64 out of int64 range")
}
n := int64(x)This prevents out-of-range conversion, but it cannot recover integer precision already lost when a large value was stored in float64.
NaN and infinity are not integers either. The same math.IsNaN and math.IsInf checks reject them before any cast. One compact guard at the conversion site is enough—you do not need a generic helper unless your program already centralizes validation.
int vs int64
Both types use the same truncation rule when you convert from float64. The difference is width: int matches the platform word size; int64 is always 64 bits.
One subtle point worth remembering: float64 cannot represent every int64 value exactly. A round trip int64 → float64 → int64 can change very large integers. When you need exact large integers, stay in integer types—or validate after conversion.
Do you need strconv for float64 to int?
Not when you already hold a float64. Avoid the round trip:
float64 → format as string → parse string → intThat path adds formatting rules and parsing errors without improving numeric accuracy. Use int(x) or int(math.Round(x)) instead.
Reach for strconv when the source data is textual—CLI flags, JSON numbers as strings, config files—not when you are converting an in-memory float. See type casting in Go for the broader conversion model.
Summary
Converting float64 to int or int64 truncates toward zero; it does not round. Choose math.Round, RoundToEven, Floor, or Ceil first when you need a different rule, then cast.
Watch two edge cases weak tutorials skip: values outside the integer range produce implementation-dependent results, and NaN or infinity should be rejected before conversion. Fractional float constants such as int(25.36) do not compile at all. Pick int64 when you need a fixed width; remember that very large int64 values may not survive a float round trip.

