在Go语言中生成指定范围内的随机数。

huangapple go评论95阅读模式
英文:

Generating random numbers over a range in Go

问题

math/rand中的所有整数函数都生成非负数。

rand.Int() int              // [0, MaxInt]
rand.Int31() int32          // [0, MaxInt32]
rand.Int31n(n int32) int32  // [0, n)
rand.Int63() int64          // [0, MaxInt64]
rand.Int63n(n int64) int64  // [0, n)
rand.Intn(n int) int        // [0, n)

我想要生成范围为**[-m, n)**的随机数。换句话说,我想要生成正数和负数的混合。

英文:

All the integer functions in math/rand generate non-negative numbers.

rand.Int() int              // [0, MaxInt]
rand.Int31() int32          // [0, MaxInt32]
rand.Int31n(n int32) int32  // [0, n)
rand.Int63() int64          // [0, MaxInt64]
rand.Int63n(n int64) int64  // [0, n)
rand.Intn(n int) int        // [0, n)

I would like to generate random numbers in the range [-m, n). In other words, I would like to generate a mix of positive and negative numbers.

答案1

得分: 95

我在Go Cookbook上找到了这个例子,它等同于rand.Range(min, max int)(如果该函数存在):

rand.Intn(max - min) + min

在调用任何rand函数之前,不要忘记初始化随机数生成器

rand.Seed(time.Now().UnixNano())
英文:

I found this example at Go Cookbook, which is equivalent to rand.Range(min, max int) (if that function existed):

rand.Intn(max - min) + min

Don't forget to seed the PRNG before calling any rand function.

rand.Seed(time.Now().UnixNano())

答案2

得分: 19

这将在给定范围[a, b]内生成随机数

rand.Seed(time.Now().UnixNano())
n := a + rand.Intn(b-a+1)

源代码

英文:

This will generate random numbers within given range [a, b]

rand.Seed(time.Now().UnixNano())
n := a + rand.Intn(b-a+1)

source

答案3

得分: 10

为了避免重复使用minmax,我建议在思考时切换rangerandom的位置。以下是我找到的符合预期的代码:

package main

import (
    "fmt"
    "math/rand"
)

// 范围规范,注意 min <= max
type IntRange struct {
    min, max int
}

// 在包括 min 和 max 的区间内获取下一个随机值
func (ir *IntRange) NextRandom(r *rand.Rand) int {
    return r.Intn(ir.max-ir.min+1) + ir.min
}

func main() {
    r := rand.New(rand.NewSource(55))
    ir := IntRange{-1, 1}
    for i := 0; i < 10; i++ {
        fmt.Println(ir.NextRandom(r))
    }
}

在 Go Playground 上查看

指定范围

你在 Cookbook 中找到的解决方案没有准确地说明 minmax 的工作方式,但当然它符合你的规范([-min, max))。我决定将范围指定为闭区间([-min, max],这意味着其边界包含在有效范围内)。与我对 Cookbook 描述的理解相比:

给出了在你指定的两个正数(在本例中为 1 和 6)之间的随机数。

(可以在 Golang Cookbook 的代码片段下方找到)

Cookbook 的实现少了一个(当然,这使它与许多乍一看很有帮助的程序保持一致)。

英文:

As to prevent repeating min and max over and over again, I suggest to switch range and random in thinking about it. This is what I found to work as expected:

package main

import (
    &quot;fmt&quot;
    &quot;math/rand&quot;
)

// range specification, note that min &lt;= max
type IntRange struct {
    min, max int
}

// get next random value within the interval including min and max
func (ir *IntRange) NextRandom(r* rand.Rand) int {
    return r.Intn(ir.max - ir.min +1) + ir.min
}

func main() {
    r := rand.New(rand.NewSource(55))
    ir := IntRange{-1,1}
    for i := 0; i&lt;10; i++ {
        fmt.Println(ir.NextRandom(r))
    }
}

See on Go Playground

Specifying the range

The solution you found in the Cookbook misses to exactly specify how min and max work, but of course it meets your specification ([-min, max)). I decided to specify the range as a closed interval ([-min, max], that means its borders are included in the valid range). Compared to my understanding of the Cookbook description:
> gives you that random number within any two positive numbers that you specify (in this case, 1 and 6).

<sub>(which can be found below the code snippet in the Golang Cookbook)</sub>

the Cookbook implementation is off by one (which of course brings it in good company with lots of programs that are helpful at first glance).

答案4

得分: 2

我为生成随机切片编写了一个小型实用程序(非常类似于Python的range函数)

代码 - https://github.com/alok87/goutils/blob/master/pkg/random/random.go

import "github.com/alok87/goutils/pkg/random"
random.RangeInt(2, 100, 5)

[3, 10, 30, 56, 67]
英文:

A small utility I wrote for generating random slices(very much like python range)

Code - https://github.com/alok87/goutils/blob/master/pkg/random/random.go

import &quot;github.com/alok87/goutils/pkg/random&quot;
random.RangeInt(2, 100, 5)

[3, 10, 30, 56, 67]

答案5

得分: 2

对我有效的解决方案是:
j = rand.Intn(600) - 100
其中m为100,n为500,它将生成从-100到499的数字。

英文:

Solution that worked for me is:

j = rand.Intn(600) - 100

where m is 100 and n is 500, it will generate numbers from -100 to 499.

答案6

得分: 1

这对我有用(生成1到10之间的随机数)...

import "math/rand"

rand.Seed(time.Now().UnixNano())
randId := rand.Intn(10-1) + 1
英文:

This worked for me (Generate random number between 1 and 10)...

import &quot;math/rand&quot;

rand.Seed(time.Now().UnixNano())
randId := rand.Intn(10-1) + 1

huangapple
  • 本文由 发表于 2014年5月10日 12:26:54
  • 转载请务必保留本文链接:https://go.coder-hub.com/23577091.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定