package main import ( "fmt" "flag" "strconv" "log" "math" "bufio" "os" ) type Opts struct { From string To string Numbers []string } func ParseOpts() Opts { var opts Opts flag.StringVar(&opts.From, "from", "", "Convert from") flag.StringVar(&opts.To, "to", "", "Convert to") flag.Parse() opts.Numbers = flag.Args() return opts } func to_si(num string) string { number, err := strconv.ParseFloat(num, 64) if err != nil { log.Fatal("that's not a number") } mag := math.Floor(math.Log10(number)) switch { case mag < 3: return num case mag == 3: // need to separate k from hundres as_k := math.Floor(float64(number) / 1000.0) mod := math.Ceil(float64(int(number) % 1000)) return fmt.Sprintf("%d.%dk", int(as_k), int(mod)) case mag > 3 && mag < 6: as_m := math.Ceil(float64(number) / 1000.0) return fmt.Sprintf("%dk", int(as_m)) case mag == 6: // need to separate mil from k as_m := math.Floor(float64(number) / 1000000.0) mod := math.Ceil(float64(int(number) % 1000000) / 1000.0) return fmt.Sprintf("%d.%dM", int(as_m), int(mod)) case mag > 6 && mag <= 9: as_m := math.Ceil(float64(number) / 1000000.0) return fmt.Sprintf("%dM", int(as_m)) default: return fmt.Sprintf("%sbesos", num) } } func main() { opts := ParseOpts() if opts.From != "" { log.Fatal("you should implement this") } if len(opts.Numbers) == 0 { scanner := bufio.NewScanner(os.Stdin) for scanner.Scan() { num := scanner.Text() fmt.Println(to_si(num)) } } else { for _, num := range opts.Numbers { fmt.Println(to_si(num)) } } }