blob: c7158a8bbcc0da333ad9fb9511f7e43c20933c08 [file] [log] [blame]
package humanize
import (
"fmt"
"math"
)
var siPrefixTable = map[float64]string{
-24: "y", // yocto
-21: "z", // zepto
-18: "a", // atto
-15: "f", // femto
-12: "p", // pico
-9: "n", // nano
-6: "ยต", // micro
-3: "m", // milli
0: "",
3: "k", // kilo
6: "M", // mega
9: "G", // giga
12: "T", // tera
15: "P", // peta
18: "E", // exa
21: "Z", // zetta
24: "Y", // yotta
}
// siNumber holds computed Value and Prefix.
// can be used with fmt.Sprintf for arbitrary formatting.
type siNumber struct {
Value float64
Prefix string
}
// NewSI returns a {Value, Prefix} struct for further formatting
func newSI(input float64) siNumber {
if input == 0 {
return siNumber{0, ""}
}
exponent := math.Floor(logn(input, 10))
exponent = math.Floor(exponent/3) * 3
value := input / math.Pow(10, exponent)
// Handle special case where value is exactly 1000.0
// Should return 1M instead of 1000k
if value == 1000.0 {
exponent += 3
value = input / math.Pow(10, exponent)
}
prefix := siPrefixTable[exponent]
return siNumber{value, prefix}
}
// SI returns a string with default formatting
// Uses Ftoa to format float value, removing trailing zeros
// e.g. SI(1000000, B) -> 1MB
// e.g. SI(2.2345e-12, "F") -> 2.2345pF
func SI(input float64, unit string) string {
si := newSI(input)
return fmt.Sprintf("%s%s%s", Ftoa(si.Value), si.Prefix, unit)
}