// Week 1 – Elementary data types in Go
// Run (from the go folder): go run ./w01/types
package main

import (
	"fmt"
	"math"
	"unsafe"
)

// Constants: their value is known at compile time and cannot change.
const (
	Pi         = 3.14159
	DaysInWeek = 7
)

func main() {
	// --- Integer types: the size is part of the type name (int8, int16, ...) ---
	fmt.Println("Integer types:")
	fmt.Printf("  int8 : %d .. %d\n", math.MinInt8, math.MaxInt8)
	fmt.Printf("  int16: %d .. %d\n", math.MinInt16, math.MaxInt16)
	fmt.Printf("  int32: %d .. %d\n", math.MinInt32, math.MaxInt32)
	fmt.Printf("  int64: %d .. %d\n", math.MinInt64, math.MaxInt64)
	fmt.Printf("  uint8 (byte): 0 .. %d\n", math.MaxUint8)
	var i int
	fmt.Printf("  int  : %d bits on this machine\n", unsafe.Sizeof(i)*8)

	// --- Real types ---
	fmt.Println("Real types:")
	fmt.Printf("  float32: max %e\n", math.MaxFloat32)
	fmt.Printf("  float64: max %e\n", math.MaxFloat64)

	// --- Literals ---
	decimal := 42
	hex := 0x2A
	binary := 0b101010
	big := 9_000_000_000 // Go has no L suffix; int is 64 bits
	var f float32 = 2.5
	d := 2.5e3
	fmt.Println("Literals:", decimal, hex, binary, big, f, d)

	// --- Character: in Go a rune is a Unicode code point (int32) ---
	c := 'A'
	fmt.Printf("Character: %c, code: %d, type: %T\n", c, c, c)
	fmt.Printf("Next character: %c\n", c+1)
	zh := '中'
	fmt.Printf("Chinese character: %c, code: %d\n", zh, zh)

	// --- Boolean type ---
	isEven := decimal%2 == 0
	fmt.Println("Is 42 even?", isEven)

	// --- Declaring variables: var (default: the "zero value") or := ---
	var count int   // 0
	var name string // ""
	var ok bool     // false
	fmt.Printf("Zero values: %d %q %v\n", count, name, ok)

	// --- Constants ---
	r := 2.0
	fmt.Println("Area of a circle (r=2):", Pi*r*r)
	fmt.Println("Number of days in 3 weeks:", 3*DaysInWeek)
}
