0 ile 1 arasında rastgele bir kayan nokta oluşturun


84

0 ile 1 arasında rastgele bir sayı oluşturmaya çalışıyorum. Okumaya devam ediyorum arc4random(), ancak ondan bir kayan nokta elde etme konusunda herhangi bir bilgi yok. Bunu nasıl yaparım?


1
Yinelemeler değil, bu açık bir şekilde float'larla ilgili tek soru gibi görünüyor.
P i

Yanıtlar:


139

[0, 1 [ (0 dahil , 1 hariç) içinde rastgele değer :

Daha ayrıntı bit burada .

Üst sınır (çift) 0xFFFFFFFF / 0x100000000 olduğundan gerçek aralık [0, 0.999999999767169356] şeklindedir.


Teşekkür ederim. Gördüğüm en basit cevap. Bağlantınızı okuyacağım ve bununla ilgili ek ayrıntılar alacağım. Tekrar teşekkürler.
jini

3
ARC4RANDOM_MAXManuel olarak tanımlanması gereken garip , ancak 0x1000000004294967296 , yani ULONG_MAX + 1. Nerede o belgelenmiştir arc4random()'ın max ULONG_MAXnasıl olsa?
bobobobo

@bobobobo, buradan: developer.apple.com/library/mac/#documentation/Darwin/Reference/… arc4random () işlevi 0 ile (2 ** 32) -1 aralığında sözde rastgele sayılar döndürür
Vladimir

8
Aslında, Jörg Bühmann tarafından şu anda bağlantıda belirtildiği gibi değer 0xFFFFFFFF, (2 ** 32) -1 == 0x100000000 - 0x1 == 0xFFFFFFFF == UINT32_MAX olmalıdır.
Josejulio

1
Bu şekilde üretilen değerlerin eşit olarak dağıtılması garanti edilmez!
kelin

107

Drand48 () ve erand48 () işlevleri, [0.0, 1.0] aralığında eşit olarak dağıtılmış, negatif olmayan, çift duyarlıklı, kayan noktalı değerleri döndürür.


19
En iyi cevap bu olmalı.
John Riselvato

Sen belki biraz cevap güncellemeniz gerekir, ben NSHipster okumak o drand48ihtiyacı bir tohum ile bir kez başlatılıyor. Elma belgelerine de başlatıldı gerektiğini düşündürmektedir.
dulaccc

1
Tohum gereklidir çünkü bu rastgele jeneratöre hesaplamalar için bir başlangıç ​​noktası verir. Bu olmadan rastgele sıra, uygulama başlatmalarında her zaman aynı olur.
Jovan Stankovic

Bu en iyi cevap.
sabiland

Bu yanıt, a için optimum kesinlikli bir yanıt değildir double. En iyi hassasiyetin nasıl elde edileceğini öğrenmek için stackoverflow.com/a/34765674/1033581 sayfasına bakın .
Cœur

16

Swift 4.2+ için bkz .: https://stackoverflow.com/a/50733095/1033581


Aşağıda, ObjC ve Swift 4.1 için doğru tekdüzelik ve optimum hassasiyet için öneriler bulunmaktadır.

32 bit hassasiyet (Optimal Float)

[0, 1] 'de (0.0 ve 1.0 dahil) tek tip rasgele değer, 32 bit hassasiyete kadar:

Obj-C :

Swift :

Şunlar için idealdir:

  • mantisi için 24 bitlik bir anlamlılık ve hassasiyete sahip bir Float(veya Float32)

48 bit hassasiyet (önerilmez)

Bu 48 bit hassasiyet elde etmek kolaydır drand48( ki kullanımları arc4random_bufbaşlık altında ). Ancak drand48'in tohum gereksinimi nedeniyle kusurları olduğunu ve ayrıca 52 bitlik Double mantis'in tümünü rastgele hale getirmek için yetersiz kaldığını unutmayın .

[0, 1] , 48 bit hassasiyette tek tip rasgele değer :

Swift :

64 bit hassasiyet ( Doubleve için en uygun Float80)

[0, 1] 'de (0.0 ve 1.0 dahil) tek tip rasgele değer, 64 bit hassasiyete kadar:

Swift , arc4random'a iki çağrı kullanarak:

Swift , arc4random_buf için bir çağrı kullanarak:

Şunlar için idealdir:

  • mantisi için anlamlı ve hassasiyeti 52 bit olan a Double(veya Float64)
  • bir Float80kendi mantis için 64 bitlik bir significand hassas olan

Notlar

Diğer yöntemlerle karşılaştırmalar

Aralığın sınırlardan birini (0 veya 1) hariç tuttuğu cevaplar muhtemelen tekdüzelik önyargısından muzdariptir ve bundan kaçınılmalıdır.

  • kullanılarak arc4random(), en hassas 1 / 0xFFFFFFFF (UINT32_MAX) olduğu
  • kullanılarak arc4random_uniform(), en hassas, 1 / 0xFFFFFFFE (UINT32_MAX-1)
  • kullanarak rand()( gizlice arc4random kullanarak ), en iyi hassasiyet 1 / 0x7FFFFFFF (RAND_MAX)
  • kullanarak random()( gizlice arc4random kullanarak ), en iyi hassasiyet 1 / 0x7FFFFFFF (RAND_MAX)

Bu tek bir çağrı ile daha iyi 32 bit hassasiyet elde etmek matematiksel olarak imkansız arc4random, arc4random_uniform, randveya random. Dolayısıyla, 32 bit ve 64 bitlik çözümlerimiz elde edebileceğimizin en iyisi olmalıdır.


'Float80' gerçek iOS cihazlarında kullanılamaz (yalnızca simülatörde çalışır).
Cœur

10

Bu işlev, negatif kayan aralıklar için de çalışır:


4
Fazladan modül işlemi. kullanmak Min+(Max-Min)*((float)arc4random())/ULONG_MAXyerine. (float)Dökme sadece paranoya.
bobobobo

@bobobobo harici modül üzerinde hemfikir olsam da, ULONG_MAX (64 bit üzerinde 18446744073709551615) yerine UINT32_MAX (her zaman 4294967295) ile bölmeyi öneririm.
Cœur


1

Tek başına "rand ()" yazan bir önceki gönderi yanlıştı. Rand () kullanmanın doğru yolu budur.

Bu 0 -> 1 arasında bir sayı oluşturacaktır

BSD belgeleri:

Rand () işlevi
, 0 ila RAND_MAX aralığında ("stdlib.h" başlık dosyasıyla tanımlandığı gibi) sözde rasgele tamsayılar dizisini hesaplar .


1

Bu, Float rasgele sayı Swift 3.1'in bir uzantısıdır


@ Cœur Teşekkürler, bunu değiştirdim
YannSteph

1

Swift 4.2

Swift 4.2, standart kitaplığa yerel ve oldukça tam özellikli bir rastgele sayı API'si içeriyor. ( Swift Evolution önerisi SE-0202 )

Tüm sayı türleri , aralığı alan ve verilen aralıktaki rastgele sayıyı döndüren statik rasgele (in :) işlevine sahiptir.


0

Arc4random () öğesinin üst sınırıyla ilgili sorunları önlemek için bunu kullanın

MAC_10_7, IPHONE_4_3 ve üstü için geçerli olduğunu unutmayın.


Bununla ilgili temel bir aralık sorunu var. Upper_bound'u 10'a ayarladığınızda kolayca fark edilir, arc4random_uniform 0'dan 9'a kadar değerler döndürür ve nihai sonuç 0,0000 ile 0,9000 arasında olur. Bunun yerine bölmelisiniz upper_bound-1. Yine de, üst sınırın neden olduğu keyfi olarak düşük bir hassasiyete sahip olursunuz, bu nedenle üst sınırı UINT32_MAX'a yükseltmelisiniz. Ve arc4random()*1.0 / UINT32_MAXbunun yerine kullanarak daha da iyi hassasiyet elde edebilirsiniz arc4random_uniform(UINT32_MAX)*1.0 / (UINT32_MAX-1).
Cœur

-1

arc4random 0x100000000 (4294967296) kadar bir aralığı vardır

Bu, 0 ile 1 arasında rastgele sayılar oluşturmak için başka bir iyi seçenektir:


arc4random maksimum değeri 0xFFFFFFFF
Cœur

Teşekkürler @ Cœur ..max val 0xFFFFFFFF bilmiyordum
Gurunatha Dogi

sizin çözümünüz de Jovan Stankovic'in cevabıyla aynı.
Cœur

Ohh bunu @
Cœur'da

-4

Bu, onbeş 0 ve 1 arasında rastgele bir kayan nokta üretir. Daha fazla bilgi burada


3
Not: yalnızca 11 ayrık değer verir: 0,0, 0,1, 0,2, ..., 1,0
TalkLittle

8
Evet, modül işlemi arc4random () 'un sonucunu 0 ile 10 arasında keser, sonra onu 10'a böler. Bu cevap genel kullanım için gerçekten kötüdür.
bobobobo

-4

varsayılan olarak 0 ile 1 arasında rastgele bir sayı (kayan) üretir.


4
Bu benim için rastgele bir int üretir.
AlexQueue

rand()iOS'ta yok gibi görünüyor ve eğer varsa, diğer * NIX'lerde olduğu gibi bir tamsayı üretecekti.
jscs

2
@JoshCaswell rand(), sırasıyla Objective-C'nin (iOS programlamasında kullanılan) bir parçası olan C'nin bir parçasıdır. C rand(), iOS'ta kesinlikle var gibi çalışır , ancak arc4random()tercih edilir.
Frungi
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.