fmt.Fprint/Fprintf 可直接写入浮点数,精度无损(值可精确表示时);需检查打开文件错误,追加应使用 os.OpenFile 配合 O_APPEND;NaN/+Inf 会输出对应字符串。

用 fmt.Fprint 或 fmt.Fprintf 写入浮点数最直接
Go 没有专门针对浮点数的文件写入函数,但 fmt 包的系列函数足够可靠。只要文件以写模式打开,fmt.Fprint 就能按默认格式把 float64 或 float32 写进去,不丢精度(前提是值本身可精确表示)。
常见错误是忘记检查 os.OpenFile 的返回错误,或者用 os.Create 覆盖了不该覆盖的文件:
-
os.Create总是截断文件,若只想追加,得用os.OpenFile(path, os.O_APPEND|os.O_WRONLY|os.O_CREATE, 0644) - 浮点数为
NaN或+Inf时,fmt会写入字符串"NaN"或,不是二进制数据——这点容易被误认为“写错了”
- 如果后续要被其他程序读取(比如 Python 的
float()),确保不用科学计数法(见下一条)
控制小数位数要用 fmt.Sprintf + strconv.FormatFloat
默认 fmt.Fprint 对 3.1415926 可能输出 3.1415926,也可能输出 3.1415926000000003(取决于底层 IEEE 754 表示)。需要固定精度时,别依赖 fmt.Printf("%f", x) ——它补零但不四舍五入到指定小数位。
正确做法是先格式化成字符串,再写入:
f, _ := os.OpenFile("data.txt", os.O_WRONLY|os.O_CREATE, 0644)
x := 3.1415926
s := strconv.FormatFloat(x, 'f', 3, 64) // 保留3位小数,64位精度
fmt.Fprint(f, s)
f.Close()
strconv.FormatFloat 比 fmt.Sprintf("%.3f", x) 更可控:它做的是真正四舍五入,且不引入额外空格或换行。
写入二进制浮点数要用 binary.Write,但需注意字节序和可移植性
如果目标是让 C 程序或内存映射工具直接读取原始 float64 值(而非文本),就得跳过文本编码,用 binary.Write:
f, _ := os.Create("data.bin")
x := 3.1415926
err := binary.Write(f, binary.LittleEndian, x)
关键点:
- 必须显式指定字节序(
binary.LittleEndian或binary.BigEndian),否则不同架构读出来是错的 - 写入的是 8 字节(
float64)或 4 字节(float32)原始数据,人类不可读,也不能用cat查看 - Go 默认用小端序,但 x86 和 ARM 通常也是小端,所以跨平台读写时,两端必须约定一致
文件关闭和错误处理不能省略
很多人只关注“怎么写”,却在 defer f.Close() 上栽跟头——如果 f 是 nil(比如 os.OpenFile 失败返回 nil, err),defer f.Close() 会 panic。
安全写法是:
f, err := os.OpenFile("out.txt", os.O_WRONLY|os.O_CREATE, 0644)
if err != nil {
log.Fatal(err)
}
defer f.Close() // 此时 f 非 nil
_, err = fmt.Fprint(f, 3.14)
if err != nil {
log.Fatal(err)
}
另外,fmt.Fprint 返回写入字节数和错误,忽略它等于放弃对磁盘满、权限不足等实际问题的感知。
浮点数本身没特殊序列化逻辑,难点全在 IO 控制流和格式选择上——选文本还是二进制,要精度还是要兼容性,这些决策比“怎么写”本身影响更大。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











