Как зайти в Даркнет?!
25th January, 01:11
6
0
Как в tkinter из поля ввода Entry получить значение в одну переменную и обновить строку кнопкой, затем получить ещё одно введённое значение и затем сложить их. Ниже пример кода
21st July, 19:00
894
0
Программа, которая создает фейковые сервера в поиске игровых серверов CS 1.6 Steam
21st March, 17:43
948
0
Очень долго работает Update запрос Oracle
27th January, 09:58
914
0
не могу запустить сервер на tomcat HTTP Status 404 – Not Found
21st January, 18:02
905
0
Где можно найти фрилансера для выполнения поступающих задач, на постоянной основе?
2nd December, 09:48
938
0
Разработка мобильной кроссплатформенной военной игры
16th July, 17:57
1724
0
период по дням
25th October, 10:44
3955
0
Пишу скрипты для BAS только на запросах
16th September, 02:42
3720
0
Некорректный скрипт для закрытия блока
14th April, 18:33
4613
0
прокидывать exception в блоках try-catch JAVA
11th March, 21:11
4381
0
Помогите пожалуйста решить задачи
24th November, 23:53
6086
0
Не понимаю почему не открывается детальное описание продукта
11th November, 11:51
4350
0
Нужно решить задачу по программированию на массивы
27th October, 18:01
4396
0
Метода Крамера С++
23rd October, 11:55
4309
0
помогите решить задачу на C++
22nd October, 17:31
4002
0
Помогите решить задачу на python с codeforces
22nd October, 11:11
4492
0
Python с нуля: полное руководство для начинающих
18th June, 13:58
2599
0
Random целое число в VB.NET
Мне нужно сгенерировать целое число random между 1 и n (где n-положительное целое число), чтобы использовать его для юнит-теста. Мне не нужно что - то слишком сложное, чтобы гарантировать истинную случайность-просто старомодное число random.
Как бы я это сделал?
Как уже неоднократно отмечалось, предложение написать такой код является проблематичным:
Public Function GetRandom(ByVal Min As Integer, ByVal Max As Integer) As Integer
Dim Generator As System.Random = New System.Random()
Return Generator.Next(Min, Max)
End Function
Причина заключается в том, что конструктор для класса Random предоставляет начальное значение по умолчанию, основанное на системных часах. В большинстве систем это имеет ограниченную степень детализации - где-то около 20 мс. поэтому, если вы напишете следующий код, вы получите одно и то же число несколько раз подряд:
Dim randoms(1000) As Integer
For i As Integer = 0 to randoms.Length - 1
randoms(i) = GetRandom(1, 100)
Next
Следующий код решает эту проблему:
Public Function GetRandom(ByVal Min As Integer, ByVal Max As Integer) As Integer
' by making Generator static, we preserve the same instance '
' (i.e., do not create new instances with the same seed over and over) '
' between calls '
Static Generator As System.Random = New System.Random()
Return Generator.Next(Min, Max)
End Function
Я собрал простую программу, использующую оба метода для генерации 25 random целых чисел между 1 и 100. Вот вам и результат:
Non-static: 70 Static: 70
Non-static: 70 Static: 46
Non-static: 70 Static: 58
Non-static: 70 Static: 19
Non-static: 70 Static: 79
Non-static: 70 Static: 24
Non-static: 70 Static: 14
Non-static: 70 Static: 46
Non-static: 70 Static: 82
Non-static: 70 Static: 31
Non-static: 70 Static: 25
Non-static: 70 Static: 8
Non-static: 70 Static: 76
Non-static: 70 Static: 74
Non-static: 70 Static: 84
Non-static: 70 Static: 39
Non-static: 70 Static: 30
Non-static: 70 Static: 55
Non-static: 70 Static: 49
Non-static: 70 Static: 21
Non-static: 70 Static: 99
Non-static: 70 Static: 15
Non-static: 70 Static: 83
Non-static: 70 Static: 26
Non-static: 70 Static: 16
Non-static: 70 Static: 75
Использовать System.Random :
Dim MyMin As Integer = 1, MyMax As Integer = 5, My1stRandomNumber As Integer, My2ndRandomNumber As Integer
' Create a random number generator
Dim Generator As System.Random = New System.Random()
' Get a random number >= MyMin and <= MyMax
My1stRandomNumber = Generator.Next(MyMin, MyMax + 1) ' Note: Next function returns numbers _less than_ max, so pass in max + 1 to include max as a possible value
' Get another random number (don't create a new generator, use the same one)
My2ndRandomNumber = Generator.Next(MyMin, MyMax + 1)
Все ответы до сих пор имеют проблемы или ошибки (множественное число, а не только один). Я вам все объясню. Но сначала я хочу похвалить проницательность Дана Тао, чтобы использовать статическую переменную для запоминания переменной генератора, так что вызов ее несколько раз не будет повторять одно и то же # снова и снова, плюс он дал очень хорошее объяснение. Но его код страдал тем же недостатком, что и большинство других, как я объясняю сейчас.
MS сделал их метод Next() довольно странным. параметр min-это минимальное включительно, как и следовало ожидать, но параметр Макс является эксклюзивным максимум, как можно было бы ожидать NOT. другими словами, если вы передадите min=1 и max=5, то ваши числа random будут любыми из 1, 2, 3 или 4, но они никогда не будут включать 5. Это первая из двух потенциальных ошибок во всем коде, использующем метод Microsoft Random.Next().
Для простого ответа (но все же с другими возможными, но редкими проблемами) вам нужно будет использовать:
Private Function GenRandomInt(min As Int32, max As Int32) As Int32
Static staticRandomGenerator As New System.Random
Return staticRandomGenerator.Next(min, max + 1)
End Function
(Мне нравится использовать Int32 , а не Integer , потому что это делает более ясным, насколько велик int, плюс он короче для ввода, но подходит вам.)
Я вижу две потенциальные проблемы с этим методом, но он будет подходящим (и правильным) для большинства применений. Так что если вы хотите простое решение, я считаю, что это правильно.
Единственные 2 проблемы, которые я вижу с этой функцией, это: 1: когда Max = Int32.MaxValue так что добавление 1 создает числовое переполнение. хотя это было бы редкостью, это все еще возможно. 2: когда мин > макс + 1. когда min = 10 и max = 5, то следующая функция выдает ошибку. это может быть то, что вы хотите. но это может быть и не так. или рассмотрим, когда min = 5 и max = 4. при добавлении 1, 5 передается в следующий метод, но он не выдает ошибку, когда это действительно ошибка, но код Microsoft .NET, который я тестировал, возвращает 5. так что это действительно не 'exclusive' max, когда max = min. но когда max < min для функции Random.Next(), то она выбрасывает ArgumentOutOfRangeException. так что реализация Microsoft действительно непоследовательна и глючит тоже в этом отношении.
вы можете просто поменять местами числа, когда min > max, чтобы не возникало ошибок, но это полностью зависит от того, что требуется. если вы хотите получить ошибку о недопустимых значениях, то, вероятно, лучше также выбросить ошибку, когда исключительный максимум Microsoft (max + 1) в нашем коде равен минимуму, где MS не может ошибиться в этом случае.
обработка обходного пути для when max = Int32.MaxValue немного неудобна, но я ожидаю опубликовать подробную функцию, которая обрабатывает обе эти ситуации. и если вы хотите другого поведения, чем то, как я его закодировал, устраивайте себя. но будьте в курсе этих 2-х вопросов.
Счастливого кодирования!
Редактировать: Поэтому мне нужен был генератор целых чисел random, и я решил закодировать его 'right'. Поэтому, если кто-то хочет получить полную функциональность, вот тот, который действительно работает. (Но он не выигрывает самый простой приз с помощью всего лишь 2 строк кода. Но и это не так уж сложно.)
''' <summary>
''' Generates a random Integer with any (inclusive) minimum or (inclusive) maximum values, with full range of Int32 values.
''' </summary>
''' <param name="inMin">Inclusive Minimum value. Lowest possible return value.</param>
''' <param name="inMax">Inclusive Maximum value. Highest possible return value.</param>
''' <returns></returns>
''' <remarks></remarks>
Private Function GenRandomInt(inMin As Int32, inMax As Int32) As Int32
Static staticRandomGenerator As New System.Random
If inMin > inMax Then Dim t = inMin : inMin = inMax : inMax = t
If inMax < Int32.MaxValue Then Return staticRandomGenerator.Next(inMin, inMax + 1)
' now max = Int32.MaxValue, so we need to work around Microsoft's quirk of an exclusive max parameter.
If inMin > Int32.MinValue Then Return staticRandomGenerator.Next(inMin - 1, inMax) + 1 ' okay, this was the easy one.
' now min and max give full range of integer, but Random.Next() does not give us an option for the full range of integer.
' so we need to use Random.NextBytes() to give us 4 random bytes, then convert that to our random int.
Dim bytes(3) As Byte ' 4 bytes, 0 to 3
staticRandomGenerator.NextBytes(bytes) ' 4 random bytes
Return BitConverter.ToInt32(bytes, 0) ' return bytes converted to a random Int32
End Function
Microsoft Пример Функции Rnd
https://msdn.microsoft.com/en-us/library/f7s023d2%28в=vs.90%29.aspx
1-инициализируйте генератор чисел random.
Randomize()
2-генерировать значение random между 1 и 6.
Dim value As Integer = CInt(Int((6 * Rnd()) + 1))
Если вы используете ответ Джозефа, который является отличным ответом, и вы запускаете их назад к спине, как это:
dim i = GetRandom(1, 1715)
dim o = GetRandom(1, 1715)
Тогда результат может повторяться снова и снова, потому что он обрабатывает вызов так быстро. Это, возможно, не было проблемой в '08, но так как процессоры сегодня намного быстрее, функция не позволяет системным часам достаточно времени, чтобы измениться до совершения второго вызова.
Поскольку функция System.Random() основана на системных часах, нам нужно предоставить достаточно времени для ее изменения до следующего вызова. Один из способов сделать это-приостановить текущий поток на 1 миллисекунду. Смотрите пример ниже:
Public Function GetRandom(ByVal min as Integer, ByVal max as Integer) as Integer
Static staticRandomGenerator As New System.Random
max += 1
Return staticRandomGenerator.Next(If(min > max, max, min), If(min > max, min, max))
End Function
Вы должны создать генератор псевдо-random чисел только один раз:
Dim Generator As System.Random = New System.Random()
Затем, если целое число достаточно для ваших нужд, вы можете использовать:
Public Function GetRandom(myGenerator As System.Random, ByVal Min As Integer, ByVal Max As Integer) As Integer
'min is inclusive, max is exclusive (dah!)
Return myGenerator.Next(Min, Max + 1)
End Function
сколько угодно раз. Использование оберточной функции оправдано только потому, что максимальное значение является исключительным - я знаю, что числа random работают таким образом, но определение .Next сбивает с толку.
Создание генератора каждый раз, когда вам нужно число, на мой взгляд, неправильно; псевдо-random числа не работают таким образом.
Во-первых, вы получаете проблему с инициализацией, которая обсуждалась в других ответах. Если вы инициализируете один раз, у вас нет этой проблемы.
Во-вторых, я вовсе не уверен, что вы получаете допустимую последовательность чисел random; скорее, вы получаете набор первого числа из нескольких различных последовательностей, которые автоматически заполняются на основе компьютерного времени. Я не уверен, что эти числа пройдут тесты, подтверждающие случайность последовательности.
Просто для справки, определение чистой функции VB для RND и RANDOMIZE (которое должно дать те же результаты BASIC (1980 лет) и все версии после этого:
Public NotInheritable Class VBMath
' Methods
Private Shared Function GetTimer() As Single
Dim now As DateTime = DateTime.Now
Return CSng((((((60 * now.Hour) + now.Minute) * 60) + now.Second) + (CDbl(now.Millisecond) / 1000)))
End Function
Public Shared Sub Randomize()
Dim timer As Single = VBMath.GetTimer
Dim projectData As ProjectData = ProjectData.GetProjectData
Dim rndSeed As Integer = projectData.m_rndSeed
Dim num3 As Integer = BitConverter.ToInt32(BitConverter.GetBytes(timer), 0)
num3 = (((num3 And &HFFFF) Xor (num3 >> &H10)) << 8)
rndSeed = ((rndSeed And -16776961) Or num3)
projectData.m_rndSeed = rndSeed
End Sub
Public Shared Sub Randomize(ByVal Number As Double)
Dim num2 As Integer
Dim projectData As ProjectData = ProjectData.GetProjectData
Dim rndSeed As Integer = projectData.m_rndSeed
If BitConverter.IsLittleEndian Then
num2 = BitConverter.ToInt32(BitConverter.GetBytes(Number), 4)
Else
num2 = BitConverter.ToInt32(BitConverter.GetBytes(Number), 0)
End If
num2 = (((num2 And &HFFFF) Xor (num2 >> &H10)) << 8)
rndSeed = ((rndSeed And -16776961) Or num2)
projectData.m_rndSeed = rndSeed
End Sub
Public Shared Function Rnd() As Single
Return VBMath.Rnd(1!)
End Function
Public Shared Function Rnd(ByVal Number As Single) As Single
Dim projectData As ProjectData = ProjectData.GetProjectData
Dim rndSeed As Integer = projectData.m_rndSeed
If (Number <> 0) Then
If (Number < 0) Then
Dim num1 As UInt64 = (BitConverter.ToInt32(BitConverter.GetBytes(Number), 0) And &HFFFFFFFF)
rndSeed = CInt(((num1 + (num1 >> &H18)) And CULng(&HFFFFFF)))
End If
rndSeed = CInt((((rndSeed * &H43FD43FD) + &HC39EC3) And &HFFFFFF))
End If
projectData.m_rndSeed = rndSeed
Return (CSng(rndSeed) / 1.677722E+07!)
End Function
End Class
В то время как Random CLASS является:
Public Class Random
' Methods
<__DynamicallyInvokable> _
Public Sub New()
Me.New(Environment.TickCount)
End Sub
<__DynamicallyInvokable> _
Public Sub New(ByVal Seed As Integer)
Me.SeedArray = New Integer(&H38 - 1) {}
Dim num4 As Integer = If((Seed = -2147483648), &H7FFFFFFF, Math.Abs(Seed))
Dim num2 As Integer = (&H9A4EC86 - num4)
Me.SeedArray(&H37) = num2
Dim num3 As Integer = 1
Dim i As Integer
For i = 1 To &H37 - 1
Dim index As Integer = ((&H15 * i) Mod &H37)
Me.SeedArray(index) = num3
num3 = (num2 - num3)
If (num3 < 0) Then
num3 = (num3 + &H7FFFFFFF)
End If
num2 = Me.SeedArray(index)
Next i
Dim j As Integer
For j = 1 To 5 - 1
Dim k As Integer
For k = 1 To &H38 - 1
Me.SeedArray(k) = (Me.SeedArray(k) - Me.SeedArray((1 + ((k + 30) Mod &H37))))
If (Me.SeedArray(k) < 0) Then
Me.SeedArray(k) = (Me.SeedArray(k) + &H7FFFFFFF)
End If
Next k
Next j
Me.inext = 0
Me.inextp = &H15
Seed = 1
End Sub
Private Function GetSampleForLargeRange() As Double
Dim num As Integer = Me.InternalSample
If ((Me.InternalSample Mod 2) = 0) Then
num = -num
End If
Dim num2 As Double = num
num2 = (num2 + 2147483646)
Return (num2 / 4294967293)
End Function
Private Function InternalSample() As Integer
Dim inext As Integer = Me.inext
Dim inextp As Integer = Me.inextp
If (++inext >= &H38) Then
inext = 1
End If
If (++inextp >= &H38) Then
inextp = 1
End If
Dim num As Integer = (Me.SeedArray(inext) - Me.SeedArray(inextp))
If (num = &H7FFFFFFF) Then
num -= 1
End If
If (num < 0) Then
num = (num + &H7FFFFFFF)
End If
Me.SeedArray(inext) = num
Me.inext = inext
Me.inextp = inextp
Return num
End Function
<__DynamicallyInvokable> _
Public Overridable Function [Next]() As Integer
Return Me.InternalSample
End Function
<__DynamicallyInvokable> _
Public Overridable Function [Next](ByVal maxValue As Integer) As Integer
If (maxValue < 0) Then
Dim values As Object() = New Object() { "maxValue" }
Throw New ArgumentOutOfRangeException("maxValue", Environment.GetResourceString("ArgumentOutOfRange_MustBePositive", values))
End If
Return CInt((Me.Sample * maxValue))
End Function
<__DynamicallyInvokable> _
Public Overridable Function [Next](ByVal minValue As Integer, ByVal maxValue As Integer) As Integer
If (minValue > maxValue) Then
Dim values As Object() = New Object() { "minValue", "maxValue" }
Throw New ArgumentOutOfRangeException("minValue", Environment.GetResourceString("Argument_MinMaxValue", values))
End If
Dim num As Long = (maxValue - minValue)
If (num <= &H7FFFFFFF) Then
Return (CInt((Me.Sample * num)) + minValue)
End If
Return (CInt(CLng((Me.GetSampleForLargeRange * num))) + minValue)
End Function
<__DynamicallyInvokable> _
Public Overridable Sub NextBytes(ByVal buffer As Byte())
If (buffer Is Nothing) Then
Throw New ArgumentNullException("buffer")
End If
Dim i As Integer
For i = 0 To buffer.Length - 1
buffer(i) = CByte((Me.InternalSample Mod &H100))
Next i
End Sub
<__DynamicallyInvokable> _
Public Overridable Function NextDouble() As Double
Return Me.Sample
End Function
<__DynamicallyInvokable> _
Protected Overridable Function Sample() As Double
Return (Me.InternalSample * 4.6566128752457969E-10)
End Function
' Fields
Private inext As Integer
Private inextp As Integer
Private Const MBIG As Integer = &H7FFFFFFF
Private Const MSEED As Integer = &H9A4EC86
Private Const MZ As Integer = 0
Private SeedArray As Integer()
End Class