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
36 changes: 36 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,8 @@ Supported math helpers:
- [SumBy](#sumby)
- [Mean](#mean)
- [MeanBy](#meanby)
- [Round](#round)
- [Truncate](#truncate)

Supported helpers for strings:

Expand Down Expand Up @@ -1449,6 +1451,40 @@ mean := lo.MeanBy([]float64{}, mapper)
// 0
```

### Round

Round returns the float32/float64 of the specified precision from rounding half away.

Precision must be between 0 and 15, if it is empty or exceeds the range, default value is 3

```go
f := Round(1.23456)
// 1.235

f := Round(1.23456, 4)
// 1.2346

f := Round(1.23456, 7)
// 1.23456
```

### Truncate

Truncate returns the float32/float64 of the specified precision from truncated.

Precision must be between 0 and 15, if it is empty or exceeds the range, default value is 3

```go
f := Truncate(1.23456)
// 1.234

f := Truncate(1.23456, 4)
// 1.2345

f := Truncate(1.23456, 7)
// 1.23456
```

### RandomString

Returns a random string of the specified length and made of the specified charset.
Expand Down
46 changes: 46 additions & 0 deletions math.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ package lo

import (
"github.com/samber/lo/internal/constraints"
"math"
"strconv"
)

// Range creates an array of numbers (positive and/or negative) with given length.
Expand Down Expand Up @@ -104,3 +106,47 @@ func MeanBy[T any, R constraints.Float | constraints.Integer](collection []T, it
var sum = SumBy(collection, iteratee)
return sum / length
}

// Round returns the float32/float64 of the specified precision from rounding half away
func Round[T float64 | float32](f T, n ...int) T {
var nn = 3
if len(n) > 0 {
if n[0] >= 0 {
nn = n[0]
if nn > 15 {
nn = 15
}
}
}
pow10N := math.Pow10(nn)
_f := float64(f)
if _f >= math.MaxFloat64/pow10N {
r, _ := strconv.ParseFloat(strconv.FormatFloat(_f, 'f', nn, 64), 64)
return T(r)
} else {
return T(math.Round(_f*pow10N) / pow10N)
}
}

// Truncate returns the float32/float64 of the specified precision from truncated
func Truncate[T float64 | float32](f T, n ...int) T {
var nn = 3
if len(n) > 0 {
nn = n[0]
if n[0] >= 0 {
nn = n[0]
if nn > 15 {
nn = 15
}
}
}
pow10N := math.Pow10(nn)
_f := float64(f)
if _f >= math.MaxFloat64/pow10N {
integer, fractional := math.Modf(_f)
v, _ := strconv.ParseFloat(strconv.FormatFloat(integer+math.Trunc(fractional*pow10N)/pow10N, 'f', -1, 64), 64)
return T(v)
} else {
return T(math.Trunc(_f*pow10N) / pow10N)
}
}
53 changes: 53 additions & 0 deletions math_example_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,3 +84,56 @@ func ExampleMeanBy() {

fmt.Printf("%v", result)
}

func ExampleRound() {
result1 := Round(1.23456)
result2 := Round(1.23456, 2)
result3 := Round(1.23456, 3)
result4 := Round(1.23456, 7)
result5 := Round(1.234999999999999, 15)
result6 := Round(1.234999999999999, 7)
result7 := Round(1.235, 14)

fmt.Printf("%v\n", result1)
fmt.Printf("%v\n", result2)
fmt.Printf("%v\n", result3)
fmt.Printf("%v\n", result4)
fmt.Printf("%v\n", result5)
fmt.Printf("%v\n", result6)
fmt.Printf("%v\n", result7)

// Output:
// 1.235
// 1.23
// 1.235
// 1.23456
// 1.234999999999999
// 1.235
// 1.235
}

func ExampleTruncate() {
result1 := Truncate(1.23456)
result2 := Truncate(1.23456, 2)
result3 := Truncate(1.23456, 4)
result4 := Truncate(1.23456, 7)
result5 := Truncate(1.2349999999999999, 15)
result6 := Truncate(1.2349999999999999, 7)
result7 := Truncate(1.2349999999999999, 14)

fmt.Printf("%v\n", result1)
fmt.Printf("%v\n", result2)
fmt.Printf("%v\n", result3)
fmt.Printf("%v\n", result4)
fmt.Printf("%v\n", result5)
fmt.Printf("%v\n", result6)
fmt.Printf("%v\n", result7)
// Output:
// 1.234
// 1.23
// 1.2345
// 1.23456
// 1.235
// 1.2349999
// 1.23499999999999
}
50 changes: 50 additions & 0 deletions math_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -127,3 +127,53 @@ func TestMeanBy(t *testing.T) {
is.Equal(result3, uint32(3))
is.Equal(result4, uint32(0))
}

func TestRound(t *testing.T) {
t.Parallel()
is := assert.New(t)

result1 := Round(0.086990000031, 5)
result2 := Round(1.23456)
result3 := Round(1.23456, 2)
result4 := Round(1.23456, 3)
result5 := Round(1.23456, 7)
result6 := Round(1.23456, 15)
result7 := Round(1.23456789, 7)
result8 := Round(1.23456, 0)
result9 := Round(1.00000000001, 5)

is.Equal(result1, 0.08699)
is.Equal(result2, 1.235)
is.Equal(result3, 1.23)
is.Equal(result4, 1.235)
is.Equal(result5, 1.23456)
is.Equal(result6, 1.23456)
is.Equal(result7, 1.2345679)
is.Equal(result8, 1.0)
is.Equal(result9, 1.0)
}

func TestTruncate(t *testing.T) {
t.Parallel()
is := assert.New(t)

result1 := Truncate(0.086990000031, 5)
result2 := Truncate(1.23456)
result3 := Truncate(1.23456, 2)
result4 := Truncate(1.23456, 3)
result5 := Truncate(1.23456, 7)
result6 := Truncate(1.23456, 15)
result7 := Truncate(1.23456789, 7)
result8 := Truncate(1.23456, 0)
result9 := Truncate(1.00000000001, 5)

is.Equal(result1, 0.08699)
is.Equal(result2, 1.234)
is.Equal(result3, 1.23)
is.Equal(result4, 1.234)
is.Equal(result5, 1.23456)
is.Equal(result6, 1.23456)
is.Equal(result7, 1.2345678)
is.Equal(result8, 1.0)
is.Equal(result9, 1.0)
}