Иван Бишевац
Иван Бишевац

Reputation: 14631

Automatic casting

I have to write program that gets a number n from the user, and then calculates the sum: 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 i into double in this statement:

s = s + (1.0 / i);

Upvotes: 6

Views: 14685

Answers (6)

Imal Hasaranga Perera
Imal Hasaranga Perera

Reputation: 10029

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

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

}

Upvotes: 0

Saul
Saul

Reputation: 18041

It simply promotes i to the closest double value before making the division.

See The Java Language Specification section 5.1.2 Widening Primitive Conversion for details.

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.

Source: Wikipedia

Upvotes: 1

Android Killer
Android Killer

Reputation: 18489

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.

Upvotes: 1

Varun Achar
Varun Achar

Reputation: 15109

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

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

Check out this post clear all your doubts:

Upvotes: 3

Mat
Mat

Reputation: 206689

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.

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

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.

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

Upvotes: 9

amit
amit

Reputation: 178421

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:

(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

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

Upvotes: 6

Related Questions