2009-01-13 12 views

Respuesta

24

¿Cuál es "un número decimal al azar"? Los decimales tienen una precisión arbitraria, por lo que generar un número con tanta aleatoriedad como puedas guardar en un decimal llevaría a almacenar toda la memoria de tu máquina.

Debe saber cuántos dígitos decimales de precisión desea en su número aleatorio, momento en el que es fácil simplemente tomar un entero al azar y dividirlo. Por ejemplo, si quieres dos dígitos por encima del punto y dos dígitos en la fracción (ver randrange here):

decimal.Decimal(random.randrange(10000))/100 
+1

. Por lo tanto, estás sugiriendo que el hecho de que haya una longitud finita significa que los resultados no son aleatorios. – monokrome

15

Desde el standard library reference:

Para crear un decimal de un flotador, primero convertirlo en una cadena. Esto sirve como un recordatorio explícito de los detalles de la conversión (incluido el error de representación).

>>> import random, decimal 
>>> decimal.Decimal(str(random.random())) 
Decimal('0.467474014342') 

¿Es esto lo que quieres decir? No me parece una pita. Puede escalarlo en cualquier rango y precisión que desee.

8

Si conoce el número de dígitos que desea después y antes de la coma, puede utilizar:

>>> import decimal 
>>> import random 
>>> def gen_random_decimal(i,d): 
... return decimal.Decimal('%d.%d' % (random.randint(0,i),random.randint(0,d))) 

... 
>>> gen_random_decimal(9999,999999) #4 digits before, 6 after 
Decimal('4262.786648') 
>>> gen_random_decimal(9999,999999) 
Decimal('8623.79391') 
>>> gen_random_decimal(9999,999999) 
Decimal('7706.492775') 
>>> gen_random_decimal(99999999999,999999999999) #11 digits before, 12 after 
Decimal('35018421976.794013996282') 
>>> 
+1

Si importa aquí: la parte fraccionaria de tal número no sería uniformemente aleatoria, debido a la eliminación de ceros a la izquierda. No puedes sacar '2.0something' de eso. – bobince

+0

Consideré esto también, pero sería mejor tomar (4, 6) como argumentos en lugar de (9999, 999999) y luego simplemente usar 10 ** 4 - 1, 10 ** 6 - 1 en el cuerpo de la función. – Kiv

+0

Estoy de acuerdo con ambos comentarios :-) –

2

El módulo aleatorio tiene más que ofrecer que "flota única que regresan", pero de todos modos:

from random import random 
from decimal import Decimal 
randdecimal = lambda: Decimal("%f" % random.random()) 

¿O me perdí algo obvio en tu pregunta?

2
decimal.Decimal(random.random() * MAX_VAL).quantize(decimal.Decimal('.01')) 
0

Otra forma de hacer un decimal aleatorio.

import random 
round(random.randint(1, 1000) * random.random(), 2) 

En este ejemplo,

  • random.randint() genera entero aleatorio en el rango especificado (inclusive),
  • random.random() genera aleatorio número de punto flotante en el rango (0.0, 1.0)
  • Finalmente, redondo() función redondeará el resultado de la multiplicación del abovementi multiplicación de valores (algo así como 254.71921934351644) al número especificado después del punto decimal (en nuestro caso obtendríamos 254.71)
+1

El OP quiere una instancia 'decimal.Decimal'. Tu código crea un 'float'. –

Cuestiones relacionadas