5 ms·
14 Character Random Number Generator in C
- unwind 10y agoCool, and even cooler that the idea is due to Knuth. I found this typo entertaining: Technically it could be replaced by any other large prime number. The most important thing is that it must have few factors, and be large enough to distribute information into the higher value bits when the integer overflows. Surely any prime number has "few factors", i.e. none other than itself and 1? I guess the "prime" in the first sentence is a typo, since the second sentence reads as if the first one didn't say "prime".
- quinnftw 10y agoI noticed that too, I think he may be referring to the fact that generating super large actual prime numbers is hard, so people use probabilistic algorithms to generate probably almost primes
- Someone 10y agoThis one isn't superlarge, by a wide shot. √2,654,435,761 = 51521.2166102, so even an extremely naive trial division loop needs just over 50k trial divisions. I haven't benchmarked it, but I think that should easily run in under a second on any phone sold in the last 10 years. If you do it a bit smarter and skip even divisors, I think it could run in under a second on 30 year old hardware (25k iterations, 200-ish cycles per loop (division was very expensive, back then) takes a 5MHz CPU)
- dfox 10y agoFor context: factor(2654435761) on original series Ti-89 takes almost exactly two seconds.
- mark-r 10y agoThe problem wasn't in proving this particular number was prime, it was finding a large prime number to begin with. I don't know what the state of the art was back in the day, but 32 bits would certainly have been too large for the Sieve of Eratosthenes.
- Someone 10y agoNo, it wasn’t. ln(2654435761) is about 22, so if you limit yourself to odd numbers, about one in 11 attempts near that number will give you a prime. At a generous one minute to prove primality of numbers in that range using trial division, and assuming you forget to bail out early when you find the first divisor, you still very likely will find a prime within an hour. Even in the 70s, when computer time cost real money, that shouldn’t deter you. (I just tried this on a Mac Mini, in Swift; finding 1000 primes took about a third of a second; 3 seconds if I forget to bail out early) Edit: as further evidence that this isn't that large a prime: we knew 2^31-1 to be prime by trial division in 1772 (Euler somehow found time to do that)
- deleted 10y ago[deleted]
- quinnftw 10y agoThis particular one isn't large, but in general a pseudo-prime will produce similar effects.
- FabHK 10y agoMy understanding was that for it to work, it must have few factors, and in particular no small ones, so easiest just to chose a large prime number.
- peff 10y agohttps://en.wikipedia.org/wiki/Linear_congruential_generator https://en.wikipedia.org/wiki/Linear_congruential_generator
- FabHK 10y agoI'm glad that the author included a disclaimer: this is fine for generating pleasing pictures, but should not be used for anything serious (such as crypto, or even Monte Carlo simulations etc.)
- jcahill84 10y agoThis is really elegant. It's always fun to find something artsy in code. We often forget how important creativity is in software engineering.
- eutectic 10y agoA 15 character 64 to 32-bit generator I devised which passes dieharder: (x+=x*x+9)>>32;
- joegosse 10y agoIs dieharder considered as the industry standard tool for testing randomness? Is it commonly used by experts? https://www.phy.duke.edu/~rgb/General/dieharder.php https://www.phy.duke.edu/~rgb/General/dieharder.php
- eutectic 10y agoDieharder works OK, and you can easily install it on Ubuntu as a command-line tool. PractRand and TestU01 are more stringent and give you more knobs to play with.
- Someone 10y agoThat can be made shorter: x+=x*x+9; Are you sure you don't mean x+=((x*x+9)>>32); (and does that need the outer parentheses?) I doubt the first passes dieharder, as (if my C isn't too rusty) it alternates between odd and even numbers.
- eutectic 10y agoI mean you assign the value of the expression to your result. e.g: uint64_t x = 0; ... uint32_t y = (x+=x*x+9)>>32;
- joegosse 10y agoThank you for the writeup. What was the tool used to generate the .GIF of the shell?