Reputation: 3086
Output of the below code is
package com.ajay.compoitepattern;
class Test {
public static void main(String[] args) {
int big = 1234567890;
float approx = big;
System.out.println(big - (approx));
System.out.println(big - (int)(approx));
}
}
The outptut to this program is
0.0
-46
My question is , if the precision was lost in the widening conversion it should have been -46 in the first sysout also, why is the first output 0.0 ?
Upvotes: 2
Views: 428
Reputation: 190
First output is 0.0 because float substract from an int and it makes whole statement in to float.
That means int big also converted into a float value. Basically you are doing is (approx - approx) as (float)big = approx.
This should be the reason why you are getting zero.
If you want just try this one too
System.out.println(big/(approx));
Operations between int
and float
converts the whole statement into float
Upvotes: 4
Reputation: 35557
Read this may help you to understand. Read this SO post too..
Let's consider your code
int big = 1234567890; // here your int big=1234567890;
float approx = big;
BigDecimal bd=BigDecimal.valueOf(approx);
System.out.println(bd); // Now you can see int to float creates approx= 1234567936;
System.out.println(big - (approx)); // In here big again casting to float since you are doing a operation with float, result is zero.
System.out.println(big - (int)(approx)); // here big=1234567890 and approx= 1234567936. so difference is -46
Upvotes: 1
Reputation: 1021
float
in Java uses 23 bit for mantissa, plus 1 implisit bit, hence 24 significant bits are available, and int
is represented by 32 bits. So there is inevitable loss of precision for int values higher than 2^23. You should use double
here, as it has a 53 significant bits, so the result will be 0 in second case.
public static void main(String[] args) {
int big = 1234567890;
double approx = big;
System.out.println(big - (approx)); // --> 0.0
System.out.println(big - (int) (approx)); // --> 0
}
Upvotes: 3
Reputation: 44808
This is covered by JLS §4.2.4:
If at least one of the operands to a binary operator is of floating-point type, then the operation is a floating-point operation, even if the other is integral.
In your first example, big - approx
, since approx
is a float
, this counts as a floating-point operation. big
is widened into a float
, and since approx
is also big
widening into a float
, the loss of precision cancels itself out, netting you an answer of zero.
In your second example, big - (int) approx
, neither operand is a floating-point type since you casted approx
to int
. The loss of precision is now present, and your answer is no longer zero.
Upvotes: 3