diff --git a/random/random.go b/random/random.go index 2e0b811..05a34ad 100644 --- a/random/random.go +++ b/random/random.go @@ -10,6 +10,8 @@ import ( "io" "math/rand" "time" + + "github.com/duke-git/lancet/v2/mathutil" ) const ( @@ -24,7 +26,7 @@ func init() { rand.Seed(time.Now().UnixNano()) } -// RandInt generate random int between min and max, maybe min, not be max. +// RandInt generate random int between [min, max). // Play: https://go.dev/play/p/pXyyAAI5YxD func RandInt(min, max int) int { if min == max { @@ -38,6 +40,22 @@ func RandInt(min, max int) int { return rand.Intn(max-min) + min } +// RandFloat generate random float64 number between [min, max) with specific precision. +// Play: todo +func RandFloat(min, max float64, precision int) float64 { + if min == max { + return min + } + + if max < min { + min, max = max, min + } + + n := rand.Float64()*(max-min) + min + + return mathutil.RoundToFloat(n, precision) +} + // RandBytes generate random byte slice. // Play: https://go.dev/play/p/EkiLESeXf8d func RandBytes(length int) []byte { @@ -144,3 +162,21 @@ func RandUniqueIntSlice(n, min, max int) []int { return nums } + +// RandFloats generate a slice of random float64 of length n that do not repeat. +// Play: https://go.dev/play/p/uBkRSOz73Ec +func RandFloats(n int, min, max float64, precision int) []float64 { + nums := make([]float64, n) + used := make(map[float64]struct{}, n) + for i := 0; i < n; { + r := RandFloat(min, max, precision) + if _, use := used[r]; use { + continue + } + used[r] = struct{}{} + nums[i] = r + i++ + } + + return nums +} diff --git a/random/random_test.go b/random/random_test.go index fabcd3a..0f0efb7 100644 --- a/random/random_test.go +++ b/random/random_test.go @@ -167,3 +167,31 @@ func TestRandSymbolChar(t *testing.T) { assert.Equal(10, len(symbolChars)) assert.Equal(true, reg.MatchString(symbolChars)) } + +func TestRandFloat(t *testing.T) { + t.Parallel() + + assert := internal.NewAssert(t, "TestRandFloat") + + r1 := RandFloat(1.1, 10.1, 2) + t.Log(r1) + assert.GreaterOrEqual(r1, 5.0) + assert.Less(r1, 10.1) + + r2 := RandFloat(1.1, 1.1, 2) + assert.Equal(1.1, r2) + + r3 := RandFloat(10.1, 1.1, 2) + assert.GreaterOrEqual(r1, 1.1) + assert.Less(r3, 10.1) +} + +func TestRandFloats(t *testing.T) { + t.Parallel() + assert := internal.NewAssert(t, "TestRandFloats") + + result := RandFloats(5, 1.0, 5.0, 2) + t.Log("TestRandFloats result: ", result) + + assert.Equal(len(result), 5) +}