How to randomly generate a long number in clojure

There is a long integer m = 38941629971148227236N. I want to generate an e between 1 <e <m and check e if they satisfy this requirement: gcd (e, m) = 1. My method is to use (long (rand m)) to generate e randomly, I got a warning :

IllegalArgumentException Value out of range for long: 1.7166121075068025E19 clojure.lang.RT.longCast (RT.java:1254) 

My code is:

 (defn find-e [m] (loop [e (long (rand m))] (if (= 1 (gcd em)) e (recur (long (rand m)))))) 

I know the result far beyond the range, but I do not know if there is a way to solve this problem?

+5
source share
2 answers

The problem is (long (rand m)) , because the random value you choose is often a lot more than it can fit into a long one. You want to make bigint not for long. Here is one way:

 (bigint (bigdec (rand 38941629971148227236N))) 

Note that choosing random numbers in this way really creates a double that will convert to bigdec, which will convert to bigit. Thus, the range of possible random values ​​is limited. Using a double as a base random number means that all possible bandages will not be created. If you want a true random selection in bigint format, take a look at this answer ... but if you don't care, if you get a lot of sense in the right one, this might work for you:

 (defn find-e [m] (loop [e (bigint (bigdec (rand m)))] (if (= 1 (gcd em)) e (recur (bigint (bigdec (rand m))))))) 
+4
source

You can build it using the knowledge from the answer to creating a random java.math.BigInteger to have a more efficient solution:

 (defn random-bigint [limit] (let [bits (.bitLength limit)] (loop [result (BigInteger. bits (ThreadLocalRandom/current))] (if (< result limit) (bigint result) (recur (BigInteger. bits (ThreadLocalRandom/current))))))) 

Then your code can reuse this function:

 (defn find-e [m] (loop [e (random-bigint m)] (if (= 1 (gcd em)) e (recur (random-bigint m))))) 

This approach is to generate random numbers and then check if it has a flaw within the desired range, which if you are very unlucky, your loop will take many iterations. You can expand it to have a limit on the number of attempts and fail with an exception if it is exceeded.

+4
source

Source: https://habr.com/ru/post/1244508/


All Articles