4

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?

Grijesh Chauhan
  • 57,103
  • 20
  • 141
  • 208
Shruti Rawat
  • 687
  • 6
  • 11
  • 24

6 Answers6

8

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.

Mac
  • 1,711
  • 3
  • 12
  • 26
7

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

  • Truncate the fractional part,
  • Perform mathematical rounding, or
  • Round the number up.

That's why the language asks you to be specific about what you want to do when converting floating-point numbers to integral types.

Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
2

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;
LaurentG
  • 11,128
  • 9
  • 51
  • 66
  • "a long can be represented as a float" <-- well, not if the long value has a high enough magnitude... – fge Jun 30 '13 at 11:00
  • You can write: every long value can be **approximated** with a float, but not vice versa. – Ingo Jul 01 '13 at 18:31
0

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.

Joni
  • 108,737
  • 14
  • 143
  • 193
0

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

Roger Lindsjö
  • 11,330
  • 1
  • 42
  • 53
0

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

Ruchira Gayan Ranaweera
  • 34,993
  • 17
  • 75
  • 115
  • Part of the number will also go missing when you go from a 64 bit `long` value to a 32 bit `float` value, so that doesn't sound very convincing. – Joni Jul 01 '13 at 18:26