Reputation: 697
My code goes like this --
public void abc{
long a=1111;
float b=a; // this works fine even though this is narrowing conversion
long c=b;// this gives compilation error
}
Can you explain why this is happening?
Upvotes: 4
Views: 4733
Reputation: 35557
Take a look at this
byte
1 signed byte (two's complement). Covers values from -128 to 127.
short
2 bytes, signed (two's complement), -32,768 to 32,767
int
4 bytes, signed (two's complement). -2,147,483,648 to 2,147,483,647.
Like all numeric types ints may be cast into other numeric types
(byte, short, long, float, double). When lossy casts are done (e.g.
int to byte) the conversion is done modulo the length of the smaller
type.
long
8 bytes signed (two's complement). Ranges from
-9,223,372,036,854,775,808 to +9,223,372,036,854,775,807.
float
4 bytes, IEEE 754. Covers a range from 1.40129846432481707e-45
to 3.40282346638528860e+38 (positive or negative).
Like all numeric types floats may be cast into other numeric types
(byte, short, long, int, double). When lossy casts to integer types
are done (e.g. float to short) the fractional part is truncated and
the conversion is done modulo the length of the smaller type.
double
8 bytes IEEE 754. Covers a range from 4.94065645841246544e-324d
to 1.79769313486231570e+308d (positive or negative).
Now you can realize if we are going to represent some float and double values in others. part of the original number(float or double) will missing. so casting is not possible in that case
Upvotes: 0
Reputation: 11543
I Java implicit widening conversions are allowed, but not narrowing. That basically means that it is ok to convert to any datatype that can hold as large or larger values the the original data type without explicitly casting the data. This does however mean that you might lose precision.
ex.
long original = Long.MAX_VALUE-1;
float f = original;
long result = (long) f;
System.err.println(original);
System.err.println(f);
System.err.println(result);
See more at JLS 5.1.2. Widening Primitive Conversion
Upvotes: 0
Reputation: 726529
When you convert from an integral type to a floating point one, it is always clear what you want to do: you change number's representation, but you keep the same number.
Converting from floating point to integral types, on the other hand, has some ambiguity: it is not clear what you would like to do with the fractional part. You may want to
That's why the language asks you to be specific about what you want to do when converting floating-point numbers to integral types.
Upvotes: 7
Reputation: 111239
The conversion rules are based on the range of numbers the data types can represent. The range allowed by long
is contained in the range allowed by float
, so an implicit conversion is allowed despite the obvious loss of precision: long stores 64 bits while float is only 32 so the conversion throws away half of the data.
Upvotes: 0
Reputation: 1495
The reason is specified in JLS 5.1.2:
It says that : long to float or double is a widening conversion.
Whereas, float to byte, short, char, int, or long is narrowing conversion.
That's why
float b=a;
is working fine in your program , since it is widening conversion.
And
long c=b;
is showing compilation error since it is a narrowing conversion.
Upvotes: 8
Reputation: 11757
Because a long
can be represented as a float
, but any float
cannot be represented as a long
. That is mathematic not Java.
Here you could add a cast to force the compilation. Of course, you could lose precision since you are converting a float
to a long
.
long c = (long) b;
Upvotes: 2