digitalmars.D.learn - How to generate a random number from system clock as seed
- Eric P626 (13/13) Jun 08 I managed to create a random number generator using the following
- Salih Dincer (3/5) Jun 08 #unix #time
- monkyyy (11/24) Jun 08 rng is an optional parameter, `uniform(0,100).writeln;` alone
- Nick Treleaven (4/8) Jun 08 That overload is used in the 2nd example.
- monkyyy (2/10) Jun 08 generate is a very rare function and do novices understand lamdas?
- Joseph Rushton Wakeling (9/11) Jun 09 The docs do tell you that `rng` is an optional parameter of
- Eric P626 (17/21) Jun 09 I don't need anything fancy. Most of the time, it's for video
- drug007 (20/34) Jun 08 ```d
- Salih Dincer (8/19) Jun 08 If UnixTime is desired, it is sufficient to have
- Eric P626 (13/24) Jun 09 I managed to use this piece of code and it worked.
- Joseph Rushton Wakeling (24/25) Jun 09 Just to be clear, do you _specifically_ want to use the system
- Steven Schveighoffer (12/25) Jun 10 I'm not sure if anyone said it explicitly, but `uniform(0, 10)`
I managed to create a random number generator using the following code: ~~~ auto rng = Random(42); //.... uniform(0,10,rng); ~~~ Now I want to seed the generator using system time. I looked at Date & time functions/classes and systime functions/classes. The problem is that they all require a time zone. But I don't need a time zone since there is no time zone. I just want the number of seconds elapsed since jan 1st 1970. In other words, the internal system clock value.
Jun 08
On Saturday, 8 June 2024 at 13:19:30 UTC, Eric P626 wrote:I just want the number of seconds elapsed since jan 1st 1970. In other words, the internal system clock value.#unix #time SDB79
Jun 08
On Saturday, 8 June 2024 at 13:19:30 UTC, Eric P626 wrote:I managed to create a random number generator using the following code: ~~~ auto rng = Random(42); //.... uniform(0,10,rng); ~~~ Now I want to seed the generator using system time. I looked at Date & time functions/classes and systime functions/classes. The problem is that they all require a time zone. But I don't need a time zone since there is no time zone. I just want the number of seconds elapsed since jan 1st 1970. In other words, the internal system clock value.rng is an optional parameter, `uniform(0,100).writeln;` alone works; the docs not telling you that is really bad the docs/api for std.time/random are bad if you need something specif Id suggest doing it yourself, but if you want to use std.time anyway the magic word I think is "localtime"(Ive pounded my head into those auto generated docs and had to dive deep to find such estoric knowledge) if you need a spefic random number from a spefic timestamp, Id suggest making a rng function from scratch and using clibs time stuff
Jun 08
On Saturday, 8 June 2024 at 16:09:04 UTC, monkyyy wrote:rng is an optional parameter, `uniform(0,100).writeln;` alone works; the docs not telling you that is really badThey do tell you:urng (optional) random number generator to use; if not specified, defaults to rndGenThat overload is used in the 2nd example. https://dlang.org/phobos/std_random.html#.uniform
Jun 08
On Saturday, 8 June 2024 at 20:53:02 UTC, Nick Treleaven wrote:On Saturday, 8 June 2024 at 16:09:04 UTC, monkyyy wrote:generate is a very rare function and do novices understand lamdas?rng is an optional parameter, `uniform(0,100).writeln;` alone works; the docs not telling you that is really badThey do tell you:urng (optional) random number generator to use; if not specified, defaults to rndGenThat overload is used in the 2nd example. https://dlang.org/phobos/std_random.html#.uniform
Jun 08
On Saturday, 8 June 2024 at 21:04:16 UTC, monkyyy wrote:generate is a very rare function and do novices understand lamdas?Yes I know lamdas, but try not to use them. I am not very picky about the exact source of time, I just want a different integer every time I run the program. But while looking at the doc, it seemed complicated because I required time zones, and I could not get the entire time stamp as a single integer.
Jun 09
On Sunday, 9 June 2024 at 07:11:22 UTC, Eric P626 wrote:On Saturday, 8 June 2024 at 21:04:16 UTC, monkyyy wrote:Im not sure exactly why it automagically works, but it does work, the defualt rng is time seeded somehowgenerate is a very rare function and do novices understand lamdas?Yes I know lamdas, but try not to use them. I am not very picky about the exact source of time, I just want a different integer every time I run the program. But while looking at the doc, it seemed complicated because I required time zones, and I could not get the entire time stamp as a single integer.I am not exactly sure what the exclamation points stand for in the first line of code.templates its a simplification but assume function headers have two parts, a compile time part and a runtime part thats from c; while it trys to fill in the compile time part implicitly if theres no information and your passing a type in, you use ! to fill the compile time header
Jun 09
On Saturday, 8 June 2024 at 16:09:04 UTC, monkyyy wrote:rng is an optional parameter, `uniform(0,100).writeln;` alone works; the docs not telling you that is really badThe docs do tell you that `rng` is an optional parameter of `uniform`: https://dlang.org/phobos/std_random.html#uniform However, there are often good reasons to want to pass a specific RNG: you may want to pick the specific RNG algorithm, and you may want to be able to know exactly how it was seeded, e.g. if you want to be able to reproduce the same results. I assume that Eric's use case may reflect that.
Jun 09
On Sunday, 9 June 2024 at 13:20:09 UTC, Joseph Rushton Wakeling wrote:On Saturday, 8 June 2024 at 16:09:04 UTC, monkyyy wrote:I don't need anything fancy. Most of the time, it's for video games, so I want to make sure the numbers are always shuffled. Here it's for maze generation, so I wan each maze to be unique. Eventually, I would like to use a fixed seed generator, so that I can generate the same maze over and over again if necessary. I guess, in that case, I could create a generator. I found the the simplest way to implement this is not to define any seed or generator and simply call: ~~~ uniform(0,2) ~~~ with the range you want. It was a bit counter intuitive because most languages have a ```rand()``` function. But I prefer specifying a range. Thanks again.rng is an optional parameter, `uniform(0,100).writeln;` alone works; the docs not telling you that is really badThe docs do tell you that `rng` is an optional parameter of
Jun 09
On 08.06.2024 16:19, Eric P626 wrote:I managed to create a random number generator using the following code: ~~~ auto rng = Random(42); //.... uniform(0,10,rng); ~~~ Now I want to seed the generator using system time. I looked at Date & time functions/classes and systime functions/classes. The problem is that they all require a time zone. But I don't need a time zone since there is no time zone. I just want the number of seconds elapsed since jan 1st 1970. In other words, the internal system clock value.```d import std; void main() { { auto rng = Random(42); auto result = generate!(() => uniform(0, 10, rng))().take(7); // the same random numbers sequence assert (result.equal([2, 7, 6, 4, 6, 5, 0])); } { const seed = castFrom!long.to!uint(Clock.currStdTime); auto rng = Random(seed); auto result = generate!(() => uniform(0, 10, rng))().take(7); // new random numbers sequence every time result.writeln; } } ```
Jun 08
On Saturday, 8 June 2024 at 18:25:20 UTC, drug007 wrote:```d { const seed = castFrom!long.to!uint(Clock.currStdTime); auto rng = Random(seed); auto result = generate!(() => uniform(0, 10, rng))().take(7); // new random numbers sequence every time result.writeln; } ```If UnixTime is desired, it is sufficient to have currTime.toUnixTime instead of currStdTime. It will not reset until January 19, 2038. ```d auto seed = to!uint(Clock.currTime.toUnixTime); ``` SDB 79
Jun 08
On Saturday, 8 June 2024 at 18:25:20 UTC, drug007 wrote:~~~ { const seed = castFrom!long.to!uint(Clock.currStdTime); auto rng = Random(seed); auto result = generate!(() => uniform(0, 10, rng))().take(7); // new random numbers sequence every time result.writeln; } } ~~~I managed to use this piece of code and it worked. ~~~ uint seed = castFrom!long.to!uint(Clock.currStdTime); auto rng = Random(seed); ~~~ I am not exactly sure what the exclamation points stand for in the first line of code. Probably, defining a type to class ```castFrom``` and function ```to```. But I get the idea that it just cast long to uint since ```Random``` requires an unsigned int. I assume from this line of code that C casting like ```(uint)varname``` would not work.
Jun 09
On 09.06.2024 16:37, Eric P626 wrote:On Saturday, 8 June 2024 at 18:25:20 UTC, drug007 wrote:`CastFrom!long` is a template instantiation. The instantiated template converts from `long` to `uint`. It is useful in meta-programming but here you can safely use other forms like c style cast: ```d const seed = cast(uint) Clock.currStdTime; ``` or ``` const seed = to!uint(Clock.currStdTime & 0xFFFF); ``` here we need to use the `0xFFFF` mask, because `to!uint` throws a conversion positive overflow when the value of `Clock.currStdTime` exceeds the value of `uint.max`. But I don't like this variant and I don't recommend it.~~~ { const seed = castFrom!long.to!uint(Clock.currStdTime); auto rng = Random(seed); auto result = generate!(() => uniform(0, 10, rng))().take(7); // new random numbers sequence every time result.writeln; } } ~~~I managed to use this piece of code and it worked. ~~~ uint seed = castFrom!long.to!uint(Clock.currStdTime); auto rng = Random(seed); ~~~ I am not exactly sure what the exclamation points stand for in the first line of code. Probably, defining a type to class ```castFrom``` and function ```to```. But I get the idea that it just cast long to uint since ```Random``` requires an unsigned int > I assume from this line of code that C casting like ```(uint)varname``` would not work.
Jun 09
On Sunday, 9 June 2024 at 23:31:47 UTC, drug007 wrote:```d const seed = cast(uint) Clock.currStdTime; ```Casting like this looks nice. It fits my type of thinking.
Jun 10
On Saturday, 8 June 2024 at 13:19:30 UTC, Eric P626 wrote:Now I want to seed the generator using system time.Just to be clear, do you _specifically_ want to use the system time, or are you aiming to use the system time to generate different seeds for each run? If the latter you might prefer to use the `unpredictableSeed()` function from `std.random`: https://dlang.org/phobos/std_random.html#unpredictableSeed That may use a variety of different methods to generate the seed, depending on the capabilities of the system, but one of the fallback options (which is actually the original implementation IIRC) uses a pseudo-random transformation of values derived from the thread ID, the process ID, and the current time in ticks as reported by the system's monotonic clock. A benefit of that is that it means that different threads in the same app, and different apps, are guaranteed to get _different_ random seeds if started at the same time. The preferred alternatives to that use different mechanisms, but should all have the same desired property of guaranteeing that different threads get different random seeds. But FWIW, if current time in ticks is valid for your use-case, `cast(ulong) MonoTime.currTime.ticks` should do. Hope that helps! Best wishes, -- Joe
Jun 09
On Saturday, 8 June 2024 at 13:19:30 UTC, Eric P626 wrote:I managed to create a random number generator using the following code: ~~~ auto rng = Random(42); //.... uniform(0,10,rng); ~~~ Now I want to seed the generator using system time. I looked at Date & time functions/classes and systime functions/classes. The problem is that they all require a time zone. But I don't need a time zone since there is no time zone. I just want the number of seconds elapsed since jan 1st 1970. In other words, the internal system clock value.I'm not sure if anyone said it explicitly, but `uniform(0, 10)` uses the default RNG [`rndGen`](https://dlang.org/phobos/std_random.html#rndGen), which is already properly seeded with an unpredictable seed: Global random number generator used by various functions in this module whenever no generator is specified. It is allocated per-thread and initialized to an unpredictable value for each thread. So unless you are explicitly doing something like saving the seed for future playback, I'd leave it off. -Steve
Jun 10