// 第 1 周 – Go 中由表示范围的局限引起的“意外”
// 运行：go run ./w01/pitfalls
package main

import (
	"fmt"
	"math"
)

func main() {
	// 1. 溢出：与 Java 一样会回绕。
	var max int32 = math.MaxInt32
	fmt.Println("MaxInt32     =", max)
	max++
	fmt.Println("MaxInt32 + 1 =", max) // -2147483648

	var b int8 = 127
	b++
	fmt.Println("int8(127) + 1 =", b) // -128

	// 注意：常量表达式中的溢出会被编译器报告：
	// var x int8 = 128   // 编译错误

	// 2. 整数除法
	fmt.Println("7 / 2   =", 7/2)   // 3
	fmt.Println("7 % 2   =", 7%2)   // 1
	fmt.Println("7 / 2.0 =", 7/2.0) // 3.5（常量表达式）

	celsius := 100.0
	a, c := 9, 5
	fmt.Println("Wrong:  ", float64(a/c)*celsius+32) // a/c == 1 !
	fmt.Println("Correct:", float64(a)/float64(c)*celsius+32)

	// Go 没有自动类型转换：int 和 float64 不能混用。
	// fmt.Println(a * celsius)  // 编译错误

	// 3. 浮点误差
	x, y := 0.1, 0.2
	sum := x + y
	fmt.Println("0.1 + 0.2 =", sum)
	fmt.Println("0.1 + 0.2 == 0.3 ?", sum == 0.3)
	const eps = 1e-9
	fmt.Println("|sum - 0.3| < eps ?", math.Abs(sum-0.3) < eps)

	// 4. 类型转换
	pi := 3.99
	fmt.Println("int(3.99) =", int(pi))               // 3 – 截断
	fmt.Println("math.Round(3.99) =", math.Round(pi)) // 4
	large := 300
	fmt.Println("int8(300) =", int8(large)) // 44 – 最低 8 位
}
