Gera uma flutuação aleatória entre 0 e 1


84

Estou tentando gerar um número aleatório entre 0 e 1. Continuo lendo sobre arc4random(), mas não há nenhuma informação sobre como obter um float dele. Como eu faço isso?


1
Não duplicatas, esta parece ser a única questão explicitamente relacionada aos carros alegóricos.
— P i

Respostas:


139

Valor aleatório em [0, 1 [ (incluindo 0, excluindo 1):

Um pouco mais de detalhes aqui .

O intervalo real é [0, 0,9999999999767169356] , pois o limite superior é (duplo) 0xFFFFFFFF / 0x100000000.


Obrigado. Resposta mais direta que já vi. Vou ler em seu link e obter detalhes adicionais sobre isso. Obrigado novamente.
— jini,

3
É estranho que ARC4RANDOM_MAXtenha que ser definido manualmente, mas 0x100000000é 4294967296 , que é ULONG_MAX + 1. Onde está documentado que arc4random()o máximo é de ULONG_MAXqualquer maneira?
— bobobobo

@bobobobo, aqui: developer.apple.com/library/mac/#documentation/Darwin/Reference/… A função arc4random () retorna números pseudo-aleatórios no intervalo de 0 a (2 ** 32) -1
— Vladimir

8
Na verdade, o valor deve ser 0xFFFFFFFF, (2 ** 32) -1 == 0x100000000 - 0x1 == 0xFFFFFFFF == UINT32_MAX conforme informado atualmente por Jörg Bühmann no link.
— Josejulio

1
Os valores gerados dessa forma não têm garantia de distribuição uniforme!
— kelin

107

As funções drand48 () e erand48 () retornam valores não negativos, de dupla precisão, de ponto flutuante, uniformemente distribuídos no intervalo [0,0, 1,0].


19
Esta deve ser a melhor resposta.
— John Riselvato de

Talvez você precise atualizar um pouco a resposta, li no NSHipster que drand48precisa ser inicializado uma vez com uma semente. A documentação da Apple também sugere que ele deve ser inicializado.
— dulaccc

1
A semente é necessária porque fornece a esse gerador aleatório um ponto de partida para os cálculos. Sem ela, a sequência aleatória sempre seria a mesma entre as inicializações do aplicativo.
— Jovan Stankovic

Esta é a melhor resposta.
— sabiland

Esta resposta não é uma resposta de precisão ideal para a double. Consulte stackoverflow.com/a/34765674/1033581 para saber como obter a melhor precisão.
— Cœur

16

Para Swift 4.2+, consulte: https://stackoverflow.com/a/50733095/1033581


Abaixo estão as recomendações para uniformidade correta e precisão ideal para ObjC e Swift 4.1.

Precisão de 32 bits (ideal para Float)

Valor aleatório uniforme em [0, 1] (incluindo 0,0 e 1,0), precisão de até 32 bits:

Obj-C :

Swift :

É ideal para:

  • a Float(ou Float32) que tem uma precisão de significando de 24 bits para sua mantissa

Precisão de 48 bits (desencorajado)

É fácil atingir a precisão de 48 bits com drand48( que usa arc4random_bufsob o capô ). Mas observe que drand48 tem falhas por causa do requisito de seed e também por ser subótimo para randomizar todos os 52 bits de Double mantissa.

Valor aleatório uniforme em [0, 1] , precisão de 48 bits:

Swift :

Precisão de 64 bits (ideal para Doublee Float80)

Valor aleatório uniforme em [0, 1] (incluindo 0,0 e 1,0), até 64 bits de precisão:

Swift , usando duas chamadas para arc4random:

Swift , usando uma chamada para arc4random_buf:

É ideal para:

  • a Double(ou Float64) que tem uma precisão de significando de 52 bits para sua mantissa
  • a Float80que tem uma precisão de significando de 64 bits para sua mantissa

Notas

Comparações com outros métodos

As respostas em que o intervalo exclui um dos limites (0 ou 1) provavelmente sofrem de um viés de uniformidade e devem ser evitadas.

  • usando arc4random(), a melhor precisão é 1 / 0xFFFFFFFF (UINT32_MAX)
  • usando arc4random_uniform(), a melhor precisão é 1 / 0xFFFFFFFE (UINT32_MAX-1)
  • usando rand()( secretamente usando arc4random ), a melhor precisão é 1 / 0x7FFFFFFF (RAND_MAX)
  • usando random()( secretamente usando arc4random ), a melhor precisão é 1 / 0x7FFFFFFF (RAND_MAX)

É matematicamente impossível atingir precisão melhor do que 32 bits com uma única chamada para arc4random, arc4random_uniform, randou random. Portanto, nossas soluções acima de 32 bits e 64 bits devem ser as melhores que podemos alcançar.


'Float80' não está disponível em dispositivos iOS reais (funciona apenas no simulador).
— Cœur

10

Esta função também funciona para intervalos de flutuação negativa:


4
Operação de módulo estranho. use em seu Min+(Max-Min)*((float)arc4random())/ULONG_MAXlugar. O (float)elenco é apenas paranóia.
— bobobobo

@bobobobo embora eu concorde com o módulo estranho, aconselho a dividir por UINT32_MAX (4294967295 sempre) em vez de ULONG_MAX (18446744073709551615 em 64 bits).
— Cœur


1

O post anterior informando "rand ()" sozinho estava incorreto. Esta é a maneira correta de usar rand ().

Isso criará um número entre 0 -> 1

Documentos BSD:

A função rand () calcula uma sequência de inteiros pseudo-aleatórios no
intervalo de 0 a RAND_MAX (conforme definido pelo arquivo de cabeçalho "stdlib.h").


1

Esta é uma extensão para o número aleatório Float Swift 3.1


@ Cœur Obrigado, eu mudo isso
— YannSteph

1

Swift 4.2

O Swift 4.2 incluiu uma API de número aleatório nativa e bastante completa na biblioteca padrão. ( Proposta de evolução rápida SE-0202 )

Todos os tipos de número têm a função aleatória estática (em :) que pega o intervalo e retorna o número aleatório no intervalo fornecido.


0

Use isso para evitar problemas com o limite superior de arc4random ()

Observe que é aplicável para MAC_10_7, IPHONE_4_3 e superior.


Há um problema de alcance fundamental com isso. É facilmente perceptível quando você define upper_bound para 10, arc4random_uniform retornará valores de 0 a 9, e o resultado final será de 0,0000 a 0,9000. Em vez disso, você deve dividir por upper_bound-1. Ainda assim, você ainda teria uma precisão arbitrariamente baixa causada por upper_bound, então você deveria aumentar upper_bound para UINT32_MAX. E você pode obter uma precisão ainda melhor usando em arc4random()*1.0 / UINT32_MAXvez de arc4random_uniform(UINT32_MAX)*1.0 / (UINT32_MAX-1).
— Cœur

-1

arc4random tem um intervalo de até 0x100000000 (4294967296)

Esta é outra boa opção para gerar números aleatórios entre 0 e 1:


O valor máximo de arc4random é 0xFFFFFFFF
— Cœur

Obrigado @ Cœur ..max val 0xFFFFFFFF eu não sabia
— Gurunatha Dogi

sua solução também é idêntica à resposta de Jovan Stankovic.
— Cœur

Ohh eu não vi isso @ Cœur
— Gurunatha Dogi

-4

Isso produz uma flutuação aleatória entre 0 e 1. Mais informações aqui


3
Nota: fornece apenas 11 valores discretos: 0,0, 0,1, 0,2, ..., 1,0
— TalkLittle

8
Sim, a operação de módulo corta o resultado de arc4random () para ficar entre 0 e 10, então ele o divide por 10. Esta resposta é realmente ruim para uso geral.
— bobobobo

-4

por padrão, produz um número aleatório (float) entre 0 e 1.


4
Isso produz um int aleatório para mim.
— AlexQueue

rand()não parece existir no iOS e, se existisse , produziria um número inteiro como em todos os outros * NIX.
— jscs

2
@JoshCaswell rand()é parte de C, que por sua vez é parte de Objective-C (que é usado na programação iOS). Funções C como rand()absolutamente existem no iOS, mas arc4random()é o preferido.
— Frungi de
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.