java 自动铸造

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7064281/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 18:30:17  来源:igfitidea点击:

Automatic casting

javacasting

提问by Иван Бишевац

I have to write program that gets a number nfrom the user, and then calculates the sum: s = 1/1 + 1/2 + ... + 1/n.

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

I wrote this code:

我写了这段代码:

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

How does Java decide to convert the int value iinto double in this statement:

Java 是如何决定i在这个语句中将 int 值转换为 double 的:

s = s + (1.0 / i);

回答by Mat

The rules that govern what type gets converted/promoted to what other type are defined in the Java Language Spec Chapter 5 - Conversions and Promotions.

Java Language Spec Chapter 5 - Conversions and Promotions中定义了控制什么类型被转换/提升为什么其他类型的规则。

Specifically for most arithmetic operations, look at the Binary Numeric Promotionsection.

特别是对于大多数算术运算,请查看二进制数字提升部分。

When an operator applies binary numeric promotion to a pair of operands, each of which must denote a value of a numeric type, the following rules apply, in order, using widening conversion (§5.1.2) to convert operands as necessary:

  • If either operand is of type double, the other is converted to double.
  • Otherwise, if either operand is of type float, the other is converted to float.

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

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

In your case, 1.0 is a double, so iis converted to a double (widening conversion). Since salready is a double, no further conversion is necessary.

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

回答by amit

if there is no match between types (and dividing a double with an int is not a match) it chooses one of the following, with (1) the highest priority:

如果类型之间没有匹配(并且将 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. 

in this case, it chosen (2), widening primitives. It does not change the double to an int, because double->int is not identity nor widening, so the only left choice is widening the int to a double

在这种情况下,它选择了(2),加宽基元。它不会将 double 更改为 int,因为 double->int 既不是标识也不是加宽,因此唯一剩下的选择是将 int 加宽为 double

more info: http://java.sun.com/docs/books/jls/third_edition/html/conversions.html#184206

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

回答by Varun Achar

When doing arithmetic on unlike types Java tends to widen the types involved so as to avoid losing information.

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

If either one of the variables is a double then java treats both variables as double.

如果其中一个变量是双精度型,则 java 将两个变量都视为双精度型。

Check out thispost clear all your doubts:

看看这篇文章解开你所有的疑惑:

回答by Android Killer

see when we will perform some operation where different types of datatype involved then the smaller type value will always be converted to higher type values so that no values will be lost in result and also values will be compatible with each other.

看看我们何时将执行一些涉及不同类型数据类型的操作,那么较小的类型值将始终转换为较高的类型值,这样结果中不会丢失任何值,并且值将彼此兼容。

回答by Saul

It simply promotes ito the closest doublevalue before making the division.

它只是在进行除法之前提升i到最接近的double值。

See The Java Language Specification section 5.1.2 Widening Primitive Conversionfor details.

有关详细信息,请参阅Java 语言规范部分 5.1.2 扩大原语转换

A tie-breaking rule that is even less biased is round half to even, namely

If the fraction of y is 0.5, then q is the even integer nearest to y.

Thus, for example, +23.5 becomes +24, +22.5 becomes +22, ?22.5 becomes ?22, and ?23.5 becomes ?24.

This method also treats positive and negative values symmetrically, and therefore is free of overall bias if the original numbers are positive or negative with equal probability. In addition, for most reasonable distributions of y values, the expected (average) value of the rounded numbers is essentially the same as that of the original numbers, even if the latter are all positive (or all negative). However, this rule will still introduce a positive bias for even numbers (including zero), and a negative bias for the odd ones.

This variant of the round-to-nearest method is also called unbiased rounding (ambiguously, and a bit abusively), convergent rounding, statistician's rounding, Dutch rounding, Gaussian rounding, or bankers' rounding. This is widely used in bookkeeping.

This is the default rounding mode used in IEEE 754 computing functions and operators.

一个更不偏向的打破平局规则是四舍五入,即

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

因此,例如,+23.5变为+24,+22.5变为+22,β22.5变为β22,并且β23.5变为β24。

该方法还对称地处理正值和负值,因此如果原始数字为正数或负数的概率相等,则不会出现整体偏差。此外,对于大多数合理的 y 值分布,四舍五入数字的预期(平均值)值与原始数字的预期(平均值)值基本相同,即使后者都是正数(或都为负数)。但是,此规则仍会为偶数(包括零)引入正偏差,并为奇数引入负偏差。

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

这是 IEEE 754 计算函数和运算符中使用的默认舍入模式。

Source: Wikipedia

资料来源:维基百科

回答by imal hasaranga perera

The Rule is very simple

规则很简单

  1. It first looks if either of operands are double, if this is true then it converts the non double operand to double range
  2. If first statement is false then it checks whether either of operands are float type, if this is true then it converts the non float operand to the float range.
  3. If none of above then java keeps the type as it is
  1. 它首先查看两个操作数是否为双精度,如果为真,则将非双精度操作数转换为双精度范围
  2. 如果第一条语句为假,则检查任一操作数是否为浮点类型,如果为真,则将非浮点操作数转换为浮点范围。
  3. 如果以上都不是,则 java 保持类型不变

See the code below to understand more clearly

看下面的代码更清楚

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

}