Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Avoid scientific formatting of floats #39

Merged
merged 1 commit into from
Feb 3, 2022
Merged
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
13 changes: 8 additions & 5 deletions perfdata/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package perfdata

import (
"fmt"
"github.com/NETWAYS/go-check"
"regexp"
"strings"
)
Expand All @@ -22,13 +23,15 @@ var validUomSlice = strings.Split(ValidUom, "|")
//
// This supports most internal types of Go and all fmt.Stringer interfaces.
func FormatNumeric(value interface{}) string {
switch value.(type) {
case float64, float32:
return fmt.Sprintf("%g", value)
switch v := value.(type) {
case float64:
return check.FormatFloat(v)
case float32:
return check.FormatFloat(float64(v))
case int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64:
return fmt.Sprintf("%d", value)
return fmt.Sprintf("%d", v)
case fmt.Stringer, string:
return fmt.Sprintf("%s", value)
return fmt.Sprint(v)
default:
panic(fmt.Sprintf("unsupported type for perfdata: %T", value))
}
Expand Down
3 changes: 2 additions & 1 deletion perfdata/util_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,10 @@ func TestFormatNumeric(t *testing.T) {
assert.Equal(t, "10", FormatNumeric(10))
assert.Equal(t, "-10", FormatNumeric(-10))
assert.Equal(t, "10", FormatNumeric(uint8(10)))
assert.Equal(t, "1234.5678", FormatNumeric(1234.5678))
assert.Equal(t, "1234.567", FormatNumeric(1234.567))
assert.Equal(t, "1234.567", FormatNumeric(float32(1234.567)))
assert.Equal(t, "1234.567", FormatNumeric("1234.567"))
assert.Equal(t, "1234567890.988", FormatNumeric(1234567890.9877))
}

func TestFormatLabel(t *testing.T) {
Expand Down
14 changes: 12 additions & 2 deletions threshold.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"math"
"regexp"
"strconv"
"strings"
)

// Defining a threshold for any numeric value
Expand Down Expand Up @@ -110,9 +111,9 @@ func (t Threshold) DoesViolate(value float64) bool {
}
}

// Convert a threshold bound to its string representation
// BoundaryToString returns the string representation of a Threshold boundary.
func BoundaryToString(value float64) (s string) {
s = fmt.Sprintf("%g", value)
s = FormatFloat(value)

// In the threshold context, the sign derives from lower and upper bound, we only need the ~ notation
if s == "+Inf" || s == "-Inf" {
Expand All @@ -121,3 +122,12 @@ func BoundaryToString(value float64) (s string) {

return
}

// FormatFloat returns a string representation of floats, avoiding scientific notation and removes trailing zeros.
func FormatFloat(value float64) string {
s := fmt.Sprintf("%.3f", value)
s = strings.TrimRight(s, "0") // remove trailing 0
s = strings.TrimRight(s, ".") // remove trailing dot

return s
}
27 changes: 19 additions & 8 deletions threshold_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,20 @@ import (
)

var testThresholds = map[string]*Threshold{
"10": {Lower: 0, Upper: 10},
"10:": {Lower: 10, Upper: PosInf},
"~:10": {Lower: NegInf, Upper: 10},
"10:20": {Lower: 10, Upper: 20},
"@10:20": {Lower: 10, Upper: 20, Inside: true},
"-10:10": {Lower: -10, Upper: 10},
"": nil,
"10": {Lower: 0, Upper: 10},
"10:": {Lower: 10, Upper: PosInf},
"~:10": {Lower: NegInf, Upper: 10},
"10:20": {Lower: 10, Upper: 20},
"@10:20": {Lower: 10, Upper: 20, Inside: true},
"-10:10": {Lower: -10, Upper: 10},
"-10.001:10.001": {Lower: -10.001, Upper: 10.001},
"": nil,
}

func TestBoundaryToString(t *testing.T) {
assert.Equal(t, "10", BoundaryToString(10))
assert.Equal(t, "10.1", BoundaryToString(10.1))
assert.Equal(t, "10.0000000000001", BoundaryToString(10.0000000000001))
assert.Equal(t, "10.001", BoundaryToString(10.001))
}

func TestParseThreshold(t *testing.T) {
Expand All @@ -30,6 +31,7 @@ func TestParseThreshold(t *testing.T) {
} else {
assert.NoError(t, err)
assert.Equal(t, ref, th)
assert.Equal(t, spec, th.String())
}
}
}
Expand Down Expand Up @@ -92,3 +94,12 @@ func TestThreshold_DoesViolate(t *testing.T) {
assert.False(t, thr.DoesViolate(20.1))
assert.False(t, thr.DoesViolate(3000))
}

func TestFormatFloat(t *testing.T) {
assert.Equal(t, "1000000000000", FormatFloat(1000000000000))
assert.Equal(t, "1000000000", FormatFloat(1000000000))
assert.Equal(t, "1234567890.988", FormatFloat(1234567890.9877))

assert.Equal(t, "-Inf", FormatFloat(NegInf))
assert.Equal(t, "+Inf", FormatFloat(PosInf))
}