2011-05-13 14 views
5

Cómo generar números aleatorios que proporcionarán resultados adecuados en la división (es decir, los resultados deben redondearse exactamente a 1 o 2 lugares después del punto decimal).Cómo generar números aleatorios que proporcionarán resultados adecuados en la división

(por ejemplo, un número entero por un número decimal proporcionar resultados decimales - he dado un conjunto de entradas de muestra a continuación)

2827 by 2.5 = 1130.8 
1747 by 0.8 = 2183.75 
425 by 0.4 = 1062.5 
935 by 0.8 = 1168.75 
+1

Lo que debería ser el rango de los divisores y los dividendos? –

+4

No es una respuesta, así que lo publico como un comentario, pero asegúrese de entender este documento, ya que podría afectar su solución: http://download.oracle.com/docs/cd/E19957-01/ 806-3568/ncg_goldberg.html – JasCav

+1

¿Qué números son los aleatorios aquí: los divisores o los dividendos? Si necesita exactamente 1 o 2 lugares decimales, ¿por qué no puede simplemente trabajar con enteros y dividir por 100 más adelante? –

Respuesta

3

Vale la pena señalar que todos los números enteros se pueden dividir por 0,4, 0,8 o 2,5 y estar representado con dos decimales. Esto es debido a que es el mismo que multiplicar por 2,5, 1,25, y 0,4


Sin embargo, si tiene un divisor para los que esto no es cierto, se puede hacer esto en un bucle.

double divisor = 2.4; 
double factor = 100/divisor; 
Random rand = new Random(); 
int maxValue = 1000; 
double ERROR = 1e-14*maxValue; 

for(int i=0;i<100;i++) { 
long randNum; 
do { 
    randNum = rand.nextInt(maxValue+1); 
    if (Math.abs(randNum * factor - (long) (randNum * factor)) > ERROR) 
     System.out.println("reject "+randNum + " => "+randNum/divisor); 
} while(Math.abs(randNum * factor - (long) (randNum * factor)) > ERROR); 
System.out.println(randNum + " => "+randNum/divisor); 

impresiones

729 => 303.75 
285 => 118.75 
84 => 35.0 
123 => 51.25 
999 => 416.25 
75 => 31.25 
reject 727 => 302.9166666666667 
reject 842 => 350.83333333333337 
504 => 210.0 
reject 368 => 153.33333333333334 
441 => 183.75 
579 => 241.25 
165 => 68.75 

esto va a generar números aleatorios hasta que tenga un número que es un múltiplo de 0,01.

+0

¿Cómo se debe invocar el código? ¿Cual es la solución? Solo veo números enteros (randNum: = long) y casi números enteros (factor RandNum *) cediendo. '14600.000000000002, 38000.0, 31300.000000000004, 25500.0, 11300.0, 37900.0, ...' ¿tal vez estoy invocando/inicializando mal? –

+0

Supongo que no está administrando su error de redondeo. Si tiene operaciones que producen un error de redondeo, debe formatearlas cuando las imprima. –

+0

¿Entonces solo produces .0, .25, .5 y .75? Entendí la pregunta, que cada fracción como .01, .02, ... .89, .99 debería producirse, no solo cuartos enteros. –

1

Si desea que el resultado 'redondee' a 2 decimales (no es realmente redondeado, es solo una representación decimal finita con dos decimales), simplemente genere el divisor y el dividendo siempre será 100, por ejemplo :

106250/100 = 1062.5 
116875/100 = 1168.75 

Si desea obtener dividendos más interesantes, divida el divisor y el dividendo. p.ej. el primero podría ser cualquiera de:

(/1): 106250/100 = 1062.5 
(/2): 53125/50 = 1062.5 
(/10): 10625/10 = 1062.5 
(/4): 26562.5/25 = 1062.5 
(/125): 850/0.8 = 1062.5 
+0

Como mi muestra indica que es un número entero dividido por un decimal que produce una respuesta con un máximo de 2 lugares decimales después del punto decimal. Sus muestras lo muestran con una división de números enteros que es incorrecta. – Joe

+2

@Joe: dijiste 'por ejemplo' es decir, esta es una de las formas posibles de hacerlo, no es la única forma de hacerlo. tiene que ser más claro. – Claudiu

4
res = input * random.nextInt (100)/100.0; 

Explicación:

se toma un número entero n, y se multiplica con algo. Si este algo es un número como 34.56, llamamos a la parte anterior al dígito decimal w (parte entera) y la parte detrás de .xy.

Si multiplica esto con n, termina con (n * w) + (n * (x/10)) + n * (y/100). Nunca habrá una cifra fraccional de 3 partes detrás del punto, ¿está de acuerdo?

Podemos combinar x e y a una sola parte, y di (n * w) + (n * (x/100)), y XY es sólo el nombre de algo de 0 a 100.

Como la parte anterior al punto decimal puede ser arbitrariamente grande, puede calcularla por separado, si necesita algo más que 0. Pero debe definir un rango de alguna manera. Si toma un entero aleatorio R para esa parte:

res = input * R * random.nextInt (100)/100.0; 

¿Necesita el divisor explicityl?

div = 100.0/(R * random.nextInt (100)); 

Scala es siempre útil, al probar código fragmenst:

val r = util.Random 
r: util.Random.type = [email protected] 

scala> def res (input: Int) = input * r.nextInt (100)/100.0; 
res: (input: Int)Double 

scala> (1 to 20).map (res) 
res338: scala.collection.immutable.IndexedSeq[Double] = 
Vector(0.48, 1.58, 0.48, 2.8, 0.15, 1.98, 5.67, 3.36, 6.93, 6.0, 9.02, 0.48, 7.41, 6.44, 9.6, 1.92, 16.66, 5.94, 7.98, 18.4) 
0

Para mí, el dividendo y el divisor son ambos números aleatorios. Tengo que generar una respuesta que no requiera el redondeo de decimales más allá de 2 decimales.

Si ese es el caso, la respuesta podría ser "no hay tal número". He aquí un pequeño programa en Java que escribí para poner a prueba esta hipótesis:

import java.text.DecimalFormat; 

public class Test { 
    public static void main(String[] args) { 
     double num = Math.PI; 
     DecimalFormat format = new DecimalFormat(
       "####################################0." + 
       "00##############################"); 
     while (true) { 
      for (int i = 1; i < Integer.MAX_VALUE; i++) { 
       double tmp = (i/num) * 100; 
       if (tmp == (long) tmp) { 
        System.err.println("Solution - " + i + " - " + 
          format.format(tmp) + " - " + format.format(num)); 
        break; 
       } 
      } 
      pi = Math.nextAfter(num, 1); 
     } 
     System.err.println("No solution for " + format.format(num)); 
    } 
} 

me encontré con esto durante 10 minutos (a partir de PI), y no encontró ningún valores de num que no tenía solución i. Pero observé que las soluciones pueden ser muy dispersas. Por ejemplo:

Gotcha! - 179453441 - 5712180438.00 - 3.1415926535897714 

Se necesitaron 179 millones de intentos para encontrar la solución para ese divisor.

0

Use setRoundingMode establezca el modo de redondeo y luego utilice el patrón de formato para su salida requerida.

Marque esta post ....

Cuestiones relacionadas