Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 38 additions & 6 deletions number.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ Source: https://gist.github.com/gorhill/5285193
import (
"math"
"strconv"
"strings"
)

var (
Expand Down Expand Up @@ -64,6 +65,36 @@ var (
// There is also a version for integer number, FormatInteger(),
// which is convenient for calls within template.
func FormatFloat(format string, n float64) string {
return formatFloat(format, n, false)
}

// FormatFloatNoTrailingZero produces a formatted number as string based on the user-specified
// criteria, omitting unneeded trailing decimal zeros.
//
// Usage: s := FormatFloatNoTrailingZero(format, n)
//
// Examples of format strings, given n = 12345.6789:
// "#,###.##" => "12,345.68"
// "#.###,######" => "12.345,6789"
//
// See FormatFloat.
func FormatFloatNoTrailingZero(format string, val float64) string {
return formatFloat(format, val, true)
}

// FormatInteger produces a formatted number as string.
// See FormatFloat.
func FormatInteger(format string, n int) string {
return FormatFloat(format, float64(n))
}

// FormatIntegerNoTrailingZero produces a formatted number as string without trailing zeros.
// See FormatFloatNoTrailingZero.
func FormatIntegerNoTrailingZero(format string, n int) string {
return FormatFloatNoTrailingZero(format, float64(n))
}

func formatFloat(format string, n float64, trimTrailingZeros bool) string {
// Special cases:
// NaN = "NaN"
// +Inf = "+Infinity"
Expand Down Expand Up @@ -183,11 +214,12 @@ func FormatFloat(format string, n float64) string {
fracStr = "000000000000000"[:precision-len(fracStr)] + fracStr
}

return signStr + intStr + decimalStr + fracStr
}
if trimTrailingZeros {
fracStr = strings.TrimRight(fracStr, "0")
if len(fracStr) == 0 {
return signStr + intStr
}
}

// FormatInteger produces a formatted number as string.
// See FormatFloat.
func FormatInteger(format string, n int) string {
return FormatFloat(format, float64(n))
return signStr + intStr + decimalStr + fracStr
}
18 changes: 18 additions & 0 deletions number_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,24 @@ func TestFormatFloat(t *testing.T) {
t.Errorf("On %v (%v, %v), got %v, wanted %v",
"integerTest", "#", 12345, got, "12345.000000000")
}

// Test FormatFloatNoTrailingZero and FormatIntegerNoTrailingZero
noTrailingTests := []TestStruct{
{"no trailing zero with decimals", "#,###.##", 12345.6, "12,345.6"},
{"no trailing zero whole number", "#,###.##", 12345.0, "12,345"},
{"no trailing zero retains significant digits", "#,###.##", 12345.68, "12,345.68"},
{"no trailing zero multiple fractional zeros", "#.###,######", 12345.6789, "12.345,6789"},
}
for _, test := range noTrailingTests {
got := FormatFloatNoTrailingZero(test.format, test.num)
if got != test.formatted {
t.Errorf("On %v (%v, %v), got %v, wanted %v",
test.name, test.format, test.num, got, test.formatted)
}
}
if gotInt := FormatIntegerNoTrailingZero("#", 12345); gotInt != "12345" {
t.Errorf("FormatIntegerNoTrailingZero got %v, wanted %v", gotInt, "12345")
}
// Test the things that could panic
panictests := []TestStruct{
{"FormatFloat(): invalid positive sign directive", "-", 12345.6789, "12,345.68"},
Expand Down