Генерирование случайных чисел по диапазону в 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). Другими словами, я хотел бы создать сочетание положительных и отрицательных чисел.

Ответ 1

Я нашел этот пример в Go Cookbook, который эквивалентен rand.Range(min, max int) (если эта функция существует):

rand.Intn(max - min) + min

Ответ 2

Что касается повторения повторений min и max снова и снова, я предлагаю переключить диапазон и случайные данные, думая об этом. Это то, что я нашел для работы, как ожидалось:

package main

import (
    "fmt"
    "math/rand"
)

// range specification, note that min <= 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<10; i++ {
        fmt.Println(ir.NextRandom(r))
    }
}

Смотрите на игровой площадке Go

Задание диапазона

Решение которое вы нашли в Cookbook, пропустило, чтобы точно определить, как работают min и max, но, конечно, соответствует вашей спецификации ([-min, max)). Я решил указать диапазон как закрытый интервал ([-min, max], чем означает, что его границы включены в допустимый диапазон). По сравнению с моим пониманием описания поваренной книги:

дает вам случайное число в любых двух положительных числах, которые вы указали (в этом случае 1 и 6).

(который можно найти ниже фрагмента кода в Поваренной книге Голанга)

реализация поваренной книги отключена одним (что, конечно же, приводит ее в хорошую компанию с большим количеством программ, которые на первый взгляд полезны).

Ответ 3

Небольшая утилита, которую я написал для генерации случайных фрагментов (очень похоже на диапазон питона)

Код - 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]

Ответ 4

Это сгенерирует случайные числа в заданном диапазоне [a, b]

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

источник