2011-08-15 11 views
6

Tengo que escribir el programa que obtiene un número n del usuario, y luego calcula la suma: s = 1/1 + 1/2 + ... + 1/n.Fundición automática

de escribir este código:

import java.util.Scanner; 

public class Test { 
    public static void main(String[] args) { 
     Scanner unos = new Scanner(System.in); 
     System.out.println("n=?"); 
     int n = unos.nextInt(); 

     double s = 0.0; 
     for (int i = 1; i <= n; i++) { 
      s = s + (1.0/i); 
     } 
     System.out.println("s=" + s); 
    } 
} 

¿Cómo funciona Java decidir convertir el valor int i doble en esta declaración:

s = s + (1.0/i); 
+0

's = s + (1.0d/(doble) i); ¿? –

+0

@The Elite Gentleman, mi código anterior funciona, solo pregunté qué es la regla de conversión. –

Respuesta

8

Las reglas que gobiernan lo el tipo se convierte/promociona a qué otro tipo se define en Java Language Spec Chapter 5 - Conversions and Promotions.

Específicamente para la mayoría de las operaciones aritméticas, consulte la sección Binary Numeric Promotion.

Cuando un operador aplica promoción numérica binaria a un par de operandos, cada uno de los cuales debe denotar un valor de un tipo numérico, se aplican las siguientes reglas, en orden, usando la ampliación de conversión (§5.1.2) para convertir operandos según sea necesario:

  • Si cualquier operando es del tipo doble, el otro se convierte a doble.
  • De lo contrario, si cualquiera de los operandos es del tipo float, el otro se convierte en float.

En su caso, 1,0 es un doble, por lo i se convierte en una doble (conversión de ampliación). Como s ya es un doble, no es necesario realizar más conversiones.

1

Simplemente promueve i al valor más cercano double antes de hacer La división.

Consulte The Java Language Specification section 5.1.2 Widening Primitive Conversion para obtener más información.

Una regla de desempate que es aún menos sesgada es la mitad redonda incluso, saber

Si la fracción de y es 0.5, entonces q es el número entero par más cercano a a y.

Así, por ejemplo, +23.5 se convierte en +24, +22.5 se convierte en +22, -22.5 se convierte en -22 y -23.5 se convierte en -24.

Este método también trata los valores positivos y negativos simétricamente, y por lo tanto está libre de sesgo general si los números originales son positivos o negativos con igual probabilidad . Además, para la mayoría de las distribuciones razonables de valores y , el valor esperado (promedio) de los números redondeados es esencialmente el mismo que el de los números originales, incluso si son todos positivos (o todos negativos). Sin embargo, esta regla aún introduce un sesgo positivo para números pares (incluido cero) y un sesgo negativo para los impares.

Esta variante del redondeo de ida y cercano a método también es llamado imparcial (ambigua, y un poco abusivamente), redondeo convergente, redondeo de estadística, holandés redondeo, el redondeo de Gauss, o redondeo de los banqueros. Esto es ampliamente utilizado en la contabilidad.

Este es el modo de redondeo predeterminado que se utiliza en las funciones y operadores informáticos IEEE 754 .

Fuente: Wikipedia

+0

el OP no está preguntando * qué * se está haciendo, él pregunta * cómo *. ¿Cómo se elige convertir el valor int en doble? – amit

5

si no hay ninguna coincidencia entre los tipos (y la división de un doble con un int no es un partido) se elige uno de los siguientes, con (1) la más alta prioridad:

(1) identity conversion 
(2) a widening primitive conversion 
(3) a widening reference conversion 
(4) a boxing conversion optionally followed by a widening reference conversion 
(5) an unboxing conversion optionally followed by a widening primitive conversion. 

en este caso, se eligió (2), primitivas de ensanchamiento.No cambia el doble a un int, ya doble> int no es la identidad ni la ampliación, por lo que la única opción que queda es cada vez mayor el int a un doble

más información: http://java.sun.com/docs/books/jls/third_edition/html/conversions.html#184206

3

Al hacer aritmética en tipos diferentes, Java tiende a ampliar los tipos implicados para evitar perder información.

Si cualquiera de las variables es una doble, java trata ambas variables como dobles.

Echa un vistazo a this posterior claras todas sus dudas:

1

ver cuando vamos a realizar alguna operación en la que diferentes tipos de tipos de datos involucrados entonces el valor de un tipo más pequeño siempre se convierten en valores de tipo más elevado de manera que no se perderán los valores en resultado y también los valores serán compatibles entre sí.

+0

¿Cómo sé cuál es el tipo de datos más pequeño y cuál es el tipo de datos más alto? –

+0

Cuando empiezas a leer cualquier idioma. Es básico conocer el tamaño de todos los tipos de datos. Al menos los tipos de datos que se usan principalmente. Así que el tamaño es más grande, es más grande o es más pequeño. –

0

La regla es muy simple

  1. Primero busca si alguno de los operandos son dobles, si esto es cierto entonces se convierte el doble de operando no duplicar gama
  2. Si la primera afirmación es falsa, entonces comprueba si cualquiera de los operandos es de tipo flotante, si esto es cierto, entonces convierte el operando flotante que no es al rango de flotación.
  3. Si ninguno de entonces java anterior mantiene el tipo, ya que es

ver el código a continuación para comprender más claramente

public static void main(String[] args) { 
    int int_val = 20; 
    double doub_val = 20.0; 
    float flo_val = 20.0f; 

    /* lets see the first statement of my answer is true */ 
    //## 1.0 I'm dividing double/float 
    System.out.println(((Object)(doub_val/flo_val)).getClass().getName()); 
    //## 1.1 I'm dividing double/int 
    System.out.println(((Object)(doub_val/int_val)).getClass().getName()); 

    //## 2.0 I'm dividing float/int 
    System.out.println(((Object)(flo_val/10)).getClass().getName()); 

    //## 3.0 I'm dividing int/int 
    System.out.println(((Object)(int_val/10)).getClass().getName()); 
    //## 3.1 I'm dividing double/double 
    System.out.println(((Object)(doub_val/10.0)).getClass().getName()); 
    //## 3.2 I'm dividing float/float 
    System.out.println(((Object)(flo_val/10.0f)).getClass().getName()); 

}