What is the C# equivalent of this VB6 Rnd() call? - c#

I am having a problem with the VB code Int(Rnd() * 75) + 75) conveting it to C#.
I have tried
Random random = new Random
random.Next( 75 ) + 75
But its isnt right. Please Help me.
Thanks

Assuming that's meant to give a value between 75 (inclusive) and 150 (exclusive) I'd use
Random random = new Random();
int value = random.Next(75, 150);
That's clearer than first generating a number in the range [0, 75) and then adding 75, IMO.
Note, however, that you shouldn't be creating a new instance of Random every time you want a random number. You probably want one instance per thread. I have a reasonably long article explaining the various pitfalls in generating random numbers, and some workarounds.

See your code in VB is doing
Generate a random number.
Multiply it with 75 and convert it into int.
Then add 75 in it.
In C# its like
Random random = new Random();
int v = random.Next() * 75 + 75;
No conversion required because random.Next() gives an integer. More over you can limit your random number generation by providing min and max value b/w which to find out like this:
random.Next(50, 100);
where it will only find random number b/w 50 and 100.

I think it like this
Random random = new Random();
int rdnum = (random.Next() + 1) * 75;
EDIT
At last if i need his random i will use this (0-20 for smaller numbers)
int rdnum = ((new Random()).Next(0, 20) + 1) * 75;
EDIT2
After comment of Deanna, code will be
Random random = new Random();
Double rdnum = (random.NextDouble() * 75) + 75;

Keep in mind that if you want exact Rnd function you can follow these steps:
1.In Solution Explorer, right click on references and click "Add Reference..."
2.In Assemblies -> Framework, check the checkbox of "Microsoft.VisualBasic"
Now you can use it like this:
Microsoft.VisualBasic.VBMath.Rnd();
Microsoft.VisualBasic.VBMath.Randomize();

Take note that Random Rnd = new Random(); should move out of for...loop in some cases:
Random Rnd = new Random();
float fRnd = (float)Rnd.NextDouble() * 75f + 75f;

Related

Random Values for an Array?

I'm looking for some help with my array. to put it in context im trying to create a console application that randomly generates a 4-digit code for the user to guess.
to do this I need an array of [3] and they need to have random numbers assigned to it.
int[] secretCode = new int[3];
secretCode[0] =
secretCode[1] =
secretCode[2] =
secretCode[3] =
My concern is what would i put here to make them generate random numbers?
thank you for your help in advance.
You can use Linq and the Random class
Random rnd = new Random();
int[] secretCode =
Enumerable.Repeat(0, 4).Select(i => rnd.Next(1000, 10000)).ToArray();
or more traditionally
int SIZE = 4;
Random rnd = new Random();
int[] secretCode = new int[SIZE];
for (int i = 0; i < SIZE; i++)
{
secretCode[i] = rnd.Next(1000, 10000);
}
Note that there is a possibility of creating the same code more than once. The solution assumes you want something in the range 1000..9999 (10000 is an exclusive upper bound) since the code is to be 4 digits. If you would also allow smaller numbers, just adjust the Select portion.
As a side note, do not create a new instance of Random inside the select, as it would likely be reseeded to the same seed, based on the system time, resulting in the same "random" number over and over. Also Random is fast, but not cryptographically strong. If you need cryptographically valid randomness use RNGCryptoServiceProvider in place of Random.

Keep getting 0 as an output in C# division

I'm trying to divide a random number that is generated by 13. It can range from 1, 53. I need to divide the random number 13 to get a whole number (to determine what suit it is in a deck of cards). I need the suit to be out of 1-4.
Random number:
value = MyRandom.Next(1, 53);
Division:
suit = value / 13;
face = value % 13;
The suit keeps generating a 0 by the way.
I'm going to take a stab in the dark as to what you're really asking.
I'm guessing you're actually getting non-zero values for suit, but you're also occasionally getting zero. The main issue here, in this case, ultimately boils down to 0-based vs 1-based indexing.
What you need to do is do all the generating/computing with 0-based indexing, and then add 1 to shift to 1-based indexing. (Alternatively, you could use 0-based indexing)
Example code:
value = MyRandom.Next(0, 52); // notice the values are inclusively between 0 and 51
suit = (value / 13) + 1; // this will be between 1 and 4
face = (value % 13) + 1; // this will be between 1 and 13
To accomplish the task you are interested in, you should use a combination of casting your value to double and performing the Math.Ceiling operator.
Your Suit code should be written as:
var suit = Math.Ceiling((double)value / 13);
It would be helpful if you posted a little more code. Random is not an easy thing for a computer to do because so much architecture goes into not doing random calculations. Therefore, the random generator in .net is a pseudorandom number sequence based off of a seed value. You can come up with your seed however you wish, but I've often seen the ticks of the current DateTime used. Here is an example using your problem and I got the expected outcome that you are looking for:
var rand = new Random((int)(DateTime.Now.Ticks % int.MaxValue));
var value = rand.Next(1, 53);
var suit = value / 13;
var face = value % 13;
Hope this helps. Good luck!

asp.net mvc c# random generating same number [duplicate]

This question already has answers here:
Random number generator only generating one random number
(15 answers)
Closed 1 year ago.
how can i generate different number,it is generating the same number
Random rand = new Random(100000);
rand.Next();
Just remove the seed number in the constructor. This seed is essentially a number from which the random number list is generated. If you specify a constant number, your random number list will always be the same.
Random rand = new Random();
rand.Next();
Your specifying the same seed try this.
Random rand = new Random();
rand.Next();
This will use the default seed which is the time.
"Initializes a new instance of the Random class, using a time-dependent default seed value."
As per MSDN : http://msdn.microsoft.com/en-us/library/system.random.aspx
Re your comment above, how to generate a "random" number in a set range.
// Generate and display 5 random integers from 50 to 100.
Console.WriteLine("Five random integers between 50 and 100:");
Console.Write("{0,8:N0}", rand.Next(50, 101));
(Taken from MSDN link above) You can now generate whatever range you want.
Not sure exactly what you are after!
Random rand = new Random(Environment.TickCount);
rand.Next();
Random rand=new Random(DateTime.Now.Millisecond);
rand.Next();
This always works for me.
Random rand = new Random();
rand.Next(0,1000); // minimum = 0, maximum = 999

Seeding a pseudo-random number generator in C#

I need a seed for an instance of C#'s Random class, and I read that most people use the current time's ticks counter for this. But that is a 64-bit value and the seed needs to be a 32-bit value. Now I thought that the GetHashCode() method, which returns an int, should provide a reasonably distributed value for its object and this may be used to avoid using only the lower 32-bits of the tick count. However, I couldn't find anything about the GetHashCode() of the Int64 datatype.
So, I know that it will not matter much, but will the following work as good as I think (I can't trial-and-error randomness), or maybe it works the same as using (int)DateTime.Now.Ticks as the seed? Or maybe it even works worse? Who can shed some light on this.
int seed = unchecked(DateTime.Now.Ticks.GetHashCode());
Random r = new Random(seed);
Edit: Why I need a seed and don't just let the Random() constructor do the work? I need to send the seed to other clients which use the same seed for the same random sequence.
new Random() already uses the current time. It is equivalent to new Random(Environment.TickCount).
But this is an implementation detail and might change in future versions of .net
I'd recommend using new Random() and only provide a fixed seed if you want to get a reproducible sequence of pseudo random values.
Since you need a known seed just use Environment.TickCount just like MS does. And then transmit it to the other program instances as seed.
If you create multiple instances of Random in a short interval (could be 16ms) they can be seeded to the same value, and thus create the same pseudo-random sequence. But that's most likely not a problem here. This common pitfall is caused by windows updating the current time(DateTime.Now/.UtcNow) and the TickCount(Environment.TickCount) only every few milliseconds. The exact interval depends on the version of windows and on what other programs are running. Typical intervals where they don't change are 16ms or 1ms.
If you need to seed it with something other than the current time (in which case you can use the default constructor), you can use this:
Random random = new Random(Guid.NewGuid().GetHashCode());
I had a similar question , to select a random set of questions from a larger list of questions. But when I use the time as the seed it gives the same random number .
So here is my solution.
int TOTALQ = 7;
int NOOFQ = 5;
int[] selectedQuestion = new int[TOTALQ];
int[] askQuestion = new int[NOOFQ];
/* Genarae a random number 1 to TOTALQ
* - if that number in selectedQuestion array is not o
* - Fill askQuestion array with that number
* - remove that number from selectedQuestion
* - if not re-do that - - while - array is not full.
*/
for (int i = 0; i < TOTALQ; i++) // fill the array
selectedQuestion[i] = 1;
int question = 0;
int seed = 1;
while (question < NOOFQ)
{
DateTime now1 = new DateTime();
now1 = DateTime.Now;
Random rand = new Random(seed+now1.Millisecond);
int RandomQuestion = rand.Next(1, TOTALQ);
Response.Write("<br/> seed " + seed + " Random number " + RandomQuestion );
if (selectedQuestion[RandomQuestion] != 0)
{
selectedQuestion[RandomQuestion] = 0; // set that q =0 so not to select
askQuestion[question] = selectedQuestion[RandomQuestion];
Response.Write(". Question no " + question + " will be question " + RandomQuestion + " from list " );
question++;
}
seed++;
}

C# Random of cordinates is linear

My code is to generate random cordinates of lat and long within a bound:
Random lastLat = new Random();
Random lastLon = new Random();
for (int i = 0; i < 50; i++)
{
int lat = lastLat.Next(516400146, 630304598); //18.51640014679267 - 18.630304598192915
int lon = lastLon.Next(224464416, 341194152); //-72.34119415283203 - -72.2244644165039
SamplePostData d0 = new SamplePostData();
d0.Location = new Location(Convert.ToDouble("18." + lat), Convert.ToDouble("-72." + lon));
AddPushpin(d0);
}
My output looks like this:
http://img263.imageshack.us/img263/7504/capturerkv.png http://img263.imageshack.us/img263/7504/capturerkv.png
Is there something wrong with how my numbers are generated?
Jørn's answer gave the problem, but not the solution: just use a single instance of Random:
Random rng = new Random();
for (int i = 0; i < 50; i++)
{
int lat = rng.Next(516400146, 630304598);
int lon = rng.Next(224464416, 341194152);
SamplePostData d0 = new SamplePostData();
d0.Location = new Location(18d + lat / 1000000000d,
-72d - lon / 1000000000d);
AddPushpin(d0);
}
(I've changed the way of using the result, too - there's no need to convert to and from a string to achieve what you want. An alternative would be to call Random.NextDouble instead and multiply it by the size of the desired range, then add a base value.)
If you're calling routine multiple times, you should probably use a single instance of Random across those multiple calls. Beware though: Random in .NET is not thread-safe. Ideally you should have a single instance per thread. See my article on randomness for more details of how to handle Random.
You are initializing both of your Random instances without an explicit seed, causing them to return the same stream of pseudo-random numbers. What you are doing now, is equivalent of using DateTime.Now as the seed for both instances. As modern computers tend to execute code really fast, you end up with the same seed in both instances.
If you use a single Random instance for generating both lang and long you should see a much more "random" distribution.
You shouldn't use two different Random objects. Draw both latitude and longitude from the same Random.
Random random = new Random();
for (int i = 0; i < 50; i++)
{
int lat = random.Next(516400146, 630304598); //18.51640014679267 - 18.630304598192915
int lon = random.Next(224464416, 341194152); //-72.34119415283203 - -72.2244644165039
SamplePostData d0 = new SamplePostData();
d0.Location = new Location(Convert.ToDouble("18." + lat), Convert.ToDouble("-72." + lon));
AddPushpin(d0);
}
Your problem is you are creating two Random objects at the same time causing them to be seeded with almost the same Time seed.
Use just ONE object.

Categories