自动铸造

时间:2011-08-15 11:13:48

标签: java casting

我必须编写从用户获得数字n的程序,然后计算总和:s = 1/1 + 1/2 + ... + 1 / n。

我写了这段代码:

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);
    }
}

Java如何决定在此语句中将int值i转换为double:

s = s + (1.0 / i);

6 个答案:

答案 0 :(得分:9)

管理将哪种类型转换/提升为Java语言规范Chapter 5 - Conversions and Promotions中定义的其他类型的规则。

特别是对于大多数算术运算,请查看Binary Numeric Promotion部分。

  

当运算符将二进制数字提升应用于一对操作数时,每个操作数必须表示数值类型的值,以下规则按顺序应用,使用扩展转换(第5.1.2节)根据需要转换操作数:

     
      
  • 如果任一操作数的类型为double,则另一个操作数将转换为double。
  •   
  • 否则,如果任一操作数的类型为float,则另一个操作数转换为float。
  •   

在您的情况下,1.0是双精度数,因此i将转换为double(加宽转换)。由于s已经是双倍,因此无需进一步转换。

答案 1 :(得分:5)

如果类型之间没有匹配(并且将double与int分开不匹配),则选择以下之一,其中(1)具有最高优先级:

(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. 

在这种情况下,它选择了(2)拓宽原语。它不会将double更改为int,因为double-&gt; int不是标识也不是加宽,所以唯一的左选择是将int加宽为double

更多信息:http://java.sun.com/docs/books/jls/third_edition/html/conversions.html#184206

答案 2 :(得分:3)

在对不同类型进行算术运算时,Java倾向于扩大所涉及的类型,以避免丢失信息。

如果其中一个变量是double,则java将这两个变量视为double。

查看this帖子,清除所有疑问:

答案 3 :(得分:1)

在进行分割之前,它只会将i提升为最接近的double值。

有关详细信息,请参阅The Java Language Specification section 5.1.2 Widening Primitive Conversion

  

一个平衡规则,即使是偏差更小的一半,甚至是   即

     

如果y的分数是0.5,则q是最接近的偶数   到了。

     

因此,例如,+ 23.5变为+ 24,+ 22.5变为+ 22,-22.5   变为-22,-23.5变为-24。

     

这种方法也可以治疗阳性   和负值对称,因此没有整体   偏差,如果原始数字是正数或负数相等   可能性。另外,对于y的大多数合理分布   值,舍入数字的预期(平均)值是   与原始数字基本相同,即使是   后者都是积极的(或全是否定的)。但是,这条规则会   仍然会对偶数(包括零)引入正偏差,并且   奇数的负偏差。

     

这种圆到最近的变体   方法也称为无偏舍入(模糊,有点   滥用),收敛舍入,统计学家舍入,荷兰语   四舍五入,高斯四舍五入或银行家四舍五入。这被广泛使用   在簿记。

     

这是IEEE 754中使用的默认舍入模式   计算功能和操作员。

来源:Wikipedia

答案 4 :(得分:1)

看看我们何时会执行一些涉及不同类型数据类型的操作,然后较小的类型值将始终转换为更高的类型值,以便结果中不会丢失任何值,并且值也将相互兼容。

答案 5 :(得分:0)

规则很简单

  1. 首先查看其中一个操作数是否为double,如果这是真的话 然后它将非双操作数转换为双范围
  2. 如果第一个语句为false,则检查是否为 操作数是浮点类型,如果这是真的则转换为非 将操作数浮动到浮动范围。
  3. 如果以上都不是,那么java保持类型
  4. 请参阅以下代码以更清楚地了解

    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());
    
    }