unstable.go 1.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445
  1. package mathx
  2. import (
  3. "math/rand"
  4. "sync"
  5. "time"
  6. )
  7. // A Unstable is used to generate random value around the mean value base on given deviation.
  8. type Unstable struct {
  9. deviation float64
  10. r *rand.Rand
  11. lock *sync.Mutex
  12. }
  13. // NewUnstable returns a Unstable.
  14. func NewUnstable(deviation float64) Unstable {
  15. if deviation < 0 {
  16. deviation = 0
  17. }
  18. if deviation > 1 {
  19. deviation = 1
  20. }
  21. return Unstable{
  22. deviation: deviation,
  23. r: rand.New(rand.NewSource(time.Now().UnixNano())),
  24. lock: new(sync.Mutex),
  25. }
  26. }
  27. // AroundDuration returns a random duration with given base and deviation.
  28. func (u Unstable) AroundDuration(base time.Duration) time.Duration {
  29. u.lock.Lock()
  30. val := time.Duration((1 + u.deviation - 2*u.deviation*u.r.Float64()) * float64(base))
  31. u.lock.Unlock()
  32. return val
  33. }
  34. // AroundInt returns a random int64 with given base and deviation.
  35. func (u Unstable) AroundInt(base int64) int64 {
  36. u.lock.Lock()
  37. val := int64((1 + u.deviation - 2*u.deviation*u.r.Float64()) * float64(base))
  38. u.lock.Unlock()
  39. return val
  40. }