Why int / byte / short / long can be converted to float / double without casting, but vice versa is impossible

My code is as follows:

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?

+4
source share
6 answers

The reason is stated in JLS 5.1.2 : It says that: long swim or double is an expanding conversion.
While float to byte, short, char, int or long narrows the conversion.
That is why float b=a; works great in your program as it extends the conversion.
And also long c=b; shows a compilation error, since this is a narrowing of the conversion.

+8
source

When you convert from an integral type to a floating point, it is always clear what you want to do: you change the numerical representation, but you keep the same number.

Converting from floating point to integral types has some ambiguity: it is not clear what you would like to do with the fractional part. You may want

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

This is why the language requires you specific information about what you want to do when converting floating point numbers to integral types.

+7
source

Since long can be represented as a float , but any float cannot be represented as a long . This is mathematically, not Java.

Here you can add a cast to force compilation. Of course, you may lose accuracy, as you convert float to long .

 long c = (long) b; 
+2
source

Conversion rules are based on a range of numbers that data types can represent. The range allowed by long is contained in the range allowed by float , so implicit conversion is allowed, despite the obvious loss of precision: long stores 64 bits and float only 32, so the conversion throws out half the data.

0
source

I allow implicit extension of Java conversions, but not narrowing. This basically means that you can convert to any data type that can contain both large and large values ​​of the original data type without explicit data entry. However, this means that you may lose accuracy.

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

More details on JLS 5.1.2. Primitive Conversion Extension

0
source

Take a look at this

 byte 1 signed byte (two complement). Covers values from -128 to 127. short 2 bytes, signed (two complement), -32,768 to 32,767 int 4 bytes, signed (two 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 (eg int to byte) the conversion is done modulo the length of the smaller type. long 8 bytes signed (two 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 (eg 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 understand if we will represent some floating and double values ​​in others. part of the original number (floating or double) will be absent. therefore, casting is not possible in this case

0
source

Source: https://habr.com/ru/post/1488943/


All Articles