2016-03-06 25 views
5

Uzun tamsayı sayısı m = 38941629971148227236N. 1 < e < m arasında bir sayı üretmek istiyorum ve bu gerekliliği yerine getirip getirmediğini kontrol etmek istiyorum: gcd (e, m) = 1. Ben uzun süre aralığının dışında sonucunu biliyoruzclojure içinde uzun bir sayı nasıl oluşturulur

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

:

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

Benim kodudur: Benim yöntemim bir uyarı var, rastgele e oluşturmak için (uzun (Rand m)) kullanmaktır ama bilmiyorum, bu sorunu çözmenin bir yolu var mı?

cevap

4

Sorun, (long (rand m)) ile ilgilidir çünkü seçtiğiniz rasgele değer genellikle uzun bir alana sığabileceğinden çok daha büyüktür. Uzun bir şey yapmak istemezsin. Bu şekilde rastgele sayılar seçerek gerçekten bigit dönüştürülür bir bigdec dönüştürüldüğü bir çift üretim olduğunu

(bigint (bigdec (rand 38941629971148227236N))) 

Not: Burada etrafında bir yoludur. Bu nedenle, olası rastgele değerlerin alanı sınırlıdır. Bir çifte baz rasgele sayı olarak kullanılması, tüm olası büyüklüklerin oluşturulmayacağı anlamına gelir. Eğer gerçek Bigint rastgele seçim istiyorsanız, this answer bakmak ... ama çok fazla bu kadar uzun zaman doğru aralığında bir bigint olsun umursamazsak bu sizin için işe yarayabilecek:

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

You generat için

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

Bu yaklaşım:

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

Sonra kod bu işlevi yeniden verebilecek: daha verimli bir çözüm olması the answer on generating random java.math.BigInteger gelen bilgiyi kullanarak inşa edebileceğini Rastgele sayılar ve daha sonra istenen aralıkta olup olmadığını kontrol etmek çok şanssız iseniz döngü çok iterasyonlar alacak bir dezavantajı vardır. Yeniden deneme sayısı sınırı olacak şekilde genişletebilir ve aşıldığı zaman bir istisna uygulanmaz.

+0

Gerçekten iyi cevap. Büyük sınırlar için, yeniden denemelerin sayısı bir sorun olmamalıdır. – muhuk

+1

Aslında yanılıyordum, her bit, arama alanını ikiye katlıyor gibi bir sorun olabilir. Ve daha büyük olan 'limit' olur, daha kötüsü olur. – muhuk

İlgili konular