This is an education project that attempts to reimplement the GNU coreutils in Go. You can find the full manual here: https://www.gnu.org/software/coreutils/manual/coreutils.html
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
go-coreutils/numfmt/main.go

78 lines
1.6 KiB

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))
}
}
}