unknwon/the-way-to-go_ZH_CN · info
math: square root of negative number %g
Error message
math: square root of negative number %g
What it means
Section 13.1.2's upgrade of the plain errors.New message: fmt.Errorf("math: square root of negative number %g", f) embeds the offending argument into the error, so the log shows which value failed instead of just that some value failed. It demonstrates fmt.Errorf as the tool for parameterized error strings (printf verbs — %g for floats), used exactly like fmt.Printf but producing an error object.
Source
Thrown at eBook/13.1.md:168
var (
EPERM Error = Errno(syscall.EPERM)
ENOENT Error = Errno(syscall.ENOENT)
ESRCH Error = Errno(syscall.ESRCH)
EINTR Error = Errno(syscall.EINTR)
EIO Error = Errno(syscall.EIO)
...
)
```
## 13.1.2 用 fmt 创建错误对象
通常你想要返回包含错误参数的更有信息量的字符串,例如:可以用 `fmt.Errorf()` 来实现:它和 `fmt.Printf()` 完全一样,接收一个或多个格式占位符的格式化字符串和相应数量的占位变量。和打印信息不同的是它用信息生成错误对象。
比如在前面的平方根例子中使用:
```go
if f < 0 {
return 0, fmt.Errorf("math: square root of negative number %g", f)
}
```
第二个例子:从命令行读取输入时,如果加了 `--help` 或 `-h` 标志,我们可以用有用的信息产生一个错误:
```go
if len(os.Args) > 1 && (os.Args[1] == "-h" || os.Args[1] == "--help") {
err = fmt.Errorf("usage: %s infile.txt outfile.txt", filepath.Base(os.Args[0]))
return
}
```
## 链接
- [目录](directory.md)
- 上一节:[错误处理与测试](13.0.md)
- 下一节:[运行时异常和 panic](13.2.md)
View on GitHub (pinned to 7a54d34d36)
Solutions
- Read the embedded value from the message to identify the offending input, then fix the producer of that value (validation, abs, clamping)
- Guard the call: if f >= 0 { ... } or pre-validate at the boundary so internal code never passes negatives
- If callers must classify, wrap a sentinel with %w: fmt.Errorf("math: square root of negative number %g: %w", f, ErrNegative) — the text is preserved and errors.Is starts working
- For genuinely negative domains use math/cmplx.Sqrt(complex(f, 0))
Example fix
// before
return 0, fmt.Errorf("math: square root of negative number %g", f)
// log shows the value, but callers cannot test the error
// after
return 0, fmt.Errorf("math: square root of negative number %g: %w", f, ErrNegative)
// errors.Is(err, ErrNegative) now matches Defensive patterns
Strategy: validation
Validate before calling
if f < 0 {
return 0, fmt.Errorf("rejecting negative input %g before sqrt", f)
}
r, err := sqrt(f) Try / catch
r, err := sqrt(x)
if err != nil {
return err // message already embeds the offending value via %g
} Prevention
- Parameterize error messages with the offending value (%g for floats) so logs are actionable
- Pre-validate domains at the boundary; internal helpers should be able to assume valid input
- Wrap a sentinel with %w if callers must programmatically detect the negative-input case
- Watch for float drift: mathematically non-negative intermediates can arrive as -1e-16; clamp with a tolerance
When it happens
Trigger: Same condition as the other sqrt examples: calling the helper with f < 0 — but now the runtime message reads e.g. 'math: square root of negative number -4'. Since it is a doc snippet, you see it after pasting the function into real code and passing a negative value.
Common situations: Reproducing failures from production logs: the %g form lets you re-run the exact failing input; debugging loops where only one batch element is negative; statistical code (variance before stddev) receiving slightly negative values from float error; callers needing to classify the error finding it is only a string.
Related errors
- I won't be able to do a sqrt of negative number!
- math - square root of negative number
- Not found error
- %s:%d:%d: %v
- usage: %s infile.txt outfile.txt
AI-assisted analysis of unknwon/the-way-to-go_ZH_CN@7a54d34d36 (2026-08-15).
Data as JSON: /api/errors/24611e30d9f036fc.
Report an issue: GitHub.