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.