// Week 1 – "Surprises" caused by the limits of representation, in Go
// Run: go run ./w01/pitfalls
package main

import (
	"fmt"
	"math"
)

func main() {
	// 1. Overflow: wraps around, just like in 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

	// Note: overflow in a constant expression is reported by the compiler:
	// var x int8 = 128   // compile error

	// 2. Integer division
	fmt.Println("7 / 2   =", 7/2)   // 3
	fmt.Println("7 % 2   =", 7%2)   // 1
	fmt.Println("7 / 2.0 =", 7/2.0) // 3.5 (constant expression)

	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 has no automatic conversion: int and float64 cannot be mixed.
	// fmt.Println(a * celsius)  // compile error

	// 3. Floating-point inaccuracy
	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. Conversion
	pi := 3.99
	fmt.Println("int(3.99) =", int(pi))               // 3 – truncates
	fmt.Println("math.Round(3.99) =", math.Round(pi)) // 4
	large := 300
	fmt.Println("int8(300) =", int8(large)) // 44 – lowest 8 bits
}
