Lors de la recherche pour cette question et lecture du code SourceCode dans (supposant des valeurs entières pour Ma question est maintenant: p> si aléatoire.py code>, j'ai commencé à me demander si randrange code> et Randint code> se comporte vraiment comme "annoncé". Je suis très enclin à croire, mais la façon dont je la lisez, randrange code> est essentiellement implémenté comme Démarrer code> et stop code>), donc randrange (1, 10) code> doit renvoyer un nombre aléatoire entre 1 et 9. p> randint (départ , arrêtez) code> appelle randrange (démarrage, arrêt + 1) code>, renvoyant ainsi un nombre compris entre 1 et 10. p> aléatoire () code> était toujours de retourner 1.0 code>, puis randint (1,10) code> retournerait 11 code >, n'est-ce pas? p> p>
3 Réponses :
de Ceci est une convention générale en mathématiques, aléatoire.py code> et les docs: ) code> indique que l'intervalle est exclusif exclusif em > 1.0. C'est-à-dire qu'il ne retournera jamais 1.0. P> [ code> et ] code> est inclusif, tandis que (< / code> et ) code> est exclusif et les deux types de parenthèses peuvent être mélangés sous forme (a, b] code> ou [a, b) code> . Jetez un coup d'œil à Wikipedia: intervalle (mathématiques) pour une explication formelle. p> p>
Je n'avais pas attrapé que ) code> (et même si j'avais eu, je n'aurais pas connu sa signification, alors merci beaucoup pour cette réponse perspicace).
@Tim: FYI, il existe plusieurs conventions différentes. Une autre convention couramment utilisée consiste à invoquer les accolades carrées, de sorte que [a, b [ code> serait un intervalle demi-ouvert équivalent à [A, B) code>.
Ce n'est pas assez, car il n'est pas évident que 0.0 <= x <1.0 code> implique que 0 <= x * n n code>, pour x code> très proche de (mais pas égal à) 1.0 code>. Heureusement, il est possible de montrer que, en supposant que ce soit à proximité, cela ne peut jamais arriver.
Point intéressant. Même s'applique aux autres langages de programmation?
Sûr; Ce n'est rien de particulièrement spécial pour python. Avec l'arithmétique à virgule flottante IEEE 754 en mode rond à proches, vous pouvez montrer que x * y x <1,0 code> et tout autre positif non minuscule < Code> y code>. (Cela peut échouer si y code> est sous-formulaire ou le plus petit nombre normal positif.)
de la documentation Python: P>
Presque toutes les fonctions du module dépendent de la fonction de base aléatoire (), qui génère un flotté aléatoire uniformément dans la plage semi-ouverte [0,0, 1.0). P> blockQuote>
Comme presque tous les nombres de flotteurs .. p>
Autres réponses ont souligné que le résultat de si vous informez Il y a deux choses qui pourraient se tromper ici: tout d'abord, lorsque nous calculons La deuxième chose qui pourrait se tromper est que le résultat de la multiplication Pour voir que cela ne peut pas arriver, il suffit de considérer la plus grande valeur possible pour Nous sommes donc en sécurité. Ouf! P>
Addendadum (2015-07-04): Le ci-dessus assume IEEE 754 Binary64 Arithmétique, avec des cravates rondes à un mode arrondi. Sur de nombreuses machines, cette hypothèse est assez sûre. Toutefois, sur des machines x86 qui utilisent le X87 FPU pour le point flottant (par exemple, diverses saveurs de Linux 32 bits), il existe une possibilité de double arrondi dans la multiplication et permettant à aléatoire () code> est toujours strictement em> moins que 1.0 code>; Cependant, ce n'est que la moitié de l'histoire. P>
randrange (n) code> comme int (aléatoire () * n) code>, vous aussi em> besoin de savoir que pour Tout flot de python x code> satisfaisant 0.0 <= x <1.0 code>, et tout entieur positif n code>, c'est vrai que 0.0 <= x * n int (x * n) code> est strictement inférieur à n code>. p>
x * n code>, n code> est implicitement converti en un flotteur. Pour assez gros n code>, cette conversion pourrait modifier la valeur. Mais si vous regardez la source Python, vous verrez qu'il utilise uniquement le int (aléatoire () * n) code> méthode pour n code> plus petit que 2 * * 53 code> (ici et ci-dessous, je suppose que la plate-forme utilise IEEE 754 doubles), qui est la gamme où la conversion de n code> sur un flotteur est garantie pour ne pas perdre d'informations (car n code> peut être représenté exactement comme un flotteur). P>
x * n code> (qui est maintenant effectué en tant que produit de flotteurs, rappelez-vous) ne sera probablement pas exactement représentable, alors Il y aura des arrondis impliqués. Si x code> est suffisamment proche de 1.0 code>, il est concevable que l'arrondi arrondira le résultat jusqu'à n code> lui-même. P>
x code>, qui est (sur presque toutes les machines que Python exécute) 1 - 2 * * -53 code>. Nous devons donc montrer que (1 - 2 ** - 53) * n n code>, car il sera toujours vrai que aléatoire () * n <= (1 - 2 ** - 53) * n code>. p>
k code> être l'entier unique k code> tel que 2 ** (k-1) n code> est n-2 ** (k-53) code>. Nous devons montrer que n * (1-2 ** 53) code> (c'est-à-dire que la valeur réelle, non fondée, du produit) est plus proche de n-2 ** (K-53 ) code> que pour n code>, de sorte qu'il sera toujours arrondi. Mais un peu d'arithmétique montre que la distance entre n * (1-2 ** - 53) code> à n code> est 2 ** - 53 * n code >, tandis que la distance entre n * (1-2 ** - 53) code> à n - 2 ** (k-53) code> est (2 ** k - n) * 2 ** - 53 code>. Mais 2 ** k - n k code> de sorte que 2 ** (k-1) n - 2 ** (k-53) code>, donc il sera em> sera arrondi (en supposant que c'est que La plate-forme fait une forme de ronde à la plus proche). P>
aléatoire () * N code> pour arrondi up em> à N code> dans le cas où aléatoire () code> renvoie la plus grande valeur possible. Le plus petit n code> pour lequel cela peut arriver est n = 2049 code>. Voir la discussion à http://bugs.python.org/issue24546 pour plus. P>
Au fait,
int (aléatoire.random () * n) code> n'est toujours pas un moyen idéal pour générer des entiers qui sont distribués de manière uniforme dans la plage(n) code>; Il y a un biais insignifiant pour le petitN code> mais devient important quen code> devient grand. J'ai ouvert un bug de Python pour cela à bugs.python.org/issue9025@Mark Dickinson: Merci! C'est fascinant.
@Mark Dickinson: Ce bogue est fixé à compter d'aujourd'hui .
vrai, à condition que vous utilisiez python> = 3.2.