unknwon/the-way-to-go_ZH_CN · error

%g is out of the int32 range

Error message

%g is out of the int32 range

What it means

Guard panic inside IntFromFloat64 (section 4.5): it refuses to convert a float64 to int when x falls outside [math.MinInt32, math.MaxInt32], panicking with '%g is out of the int32 range'. A raw Go float-to-int conversion in that situation silently overflows/truncates, so the function aborts instead of returning garbage. NaN and ±Inf also fail both comparisons and therefore panic too.

Source

Thrown at eBook/04.5.md:216

	if 0 <= n && n <= math.MaxUint8 { // conversion is safe
		return uint8(n), nil
	}
	return 0, fmt.Errorf("%d is out of the uint8 range", n)
}
```

或者安全地从 `float64` 转换为 `int`:

```go
func IntFromFloat64(x float64) int {
	if math.MinInt32 <= x && x <= math.MaxInt32 { // x lies in the integer range
		whole, fraction := math.Modf(x)
		if fraction >= 0.5 {
			whole++
		}
		return int(whole)
	}
	panic(fmt.Sprintf("%g is out of the int32 range", x))
}
```

不过如果你实际存的数字超出你要转换到的类型的取值范围的话,则会引发 `panic`([第 13.2 节](./13.2.md))。

**问题 4.1** `int` 和 `int64` 是相同的类型吗?

### 4.5.2.2 复数

Go 拥有以下复数类型:

	complex64 (32 位实数和虚数)
	complex128 (64 位实数和虚数)

复数使用 `re+imI` 来表示,其中 `re` 代表实数部分,`im` 代表虚数部分,`I` 代表根号负 1。

示例:

View on GitHub (pinned to 7a54d34d36)

Solutions

  1. Range-check (or clamp) the value before calling: if math.MinInt32 <= x && x <= math.MaxInt32
  2. Reject NaN and ±Inf explicitly before the conversion — they silently fail the range test and panic
  3. Convert to int64 or keep float64 when the wider type suffices for the data
  4. Refactor IntFromFloat64 to return (int, error) or (int, bool) instead of panicking so callers can react

Example fix

// before
func IntFromFloat64(x float64) int {
    if math.MinInt32 <= x && x <= math.MaxInt32 { ... }
    panic(fmt.Sprintf("%g is out of the int32 range", x))
}

// after
func IntFromFloat64(x float64) (int, error) {
    if math.IsNaN(x) || math.IsInf(x, 0) || x < math.MinInt32 || x > math.MaxInt32 {
        return 0, fmt.Errorf("%g is out of the int32 range", x)
    }
    return int(x), nil
}
Defensive patterns

Strategy: validation

Validate before calling

func convertibleToInt32(x float64) bool {
    if math.IsNaN(x) || math.IsInf(x, 0) {
        return false
    }
    return math.MinInt32 <= x && x <= math.MaxInt32
}

if !convertibleToInt32(v) {
    return 0, fmt.Errorf("value %g not representable as int32", v)
}
return IntFromFloat64(v), nil

Type guard

// narrows float64 inputs to the safe-conversion subset
func isSafeInt32Float(x float64) bool {
    return !math.IsNaN(x) && !math.IsInf(x, 0) &&
        x >= math.MinInt32 && x <= math.MaxInt32
}

Try / catch

defer func() {
    if r := recover(); r != nil {
        return 0, fmt.Errorf("conversion failed: %v", r)
    }
}()
return IntFromFloat64(x), nil

Prevention

When it happens

Trigger: Calling IntFromFloat64 with 1e20, float64(math.MaxInt32)*2, math.Inf(1), or math.NaN() — the two-sided range test 'math.MinInt32 <= x && x <= math.MaxInt32' is false for all of them.

Common situations: Aggregations (sums, averages) that grow past int32; converting user-parsed floats from strconv.ParseFloat; a division by zero producing +Inf that later flows into the conversion; 32-bit-platform assumptions baked into the constant.

Related errors


AI-assisted analysis of unknwon/the-way-to-go_ZH_CN@7a54d34d36 (2026-08-15). Data as JSON: /api/errors/9e5d691274ab639c. Report an issue: GitHub.