1

In java the hierarchy for implicit conversion is byte -> short -> int -> long -> float -> double Long can hold 8 bytes of data. Then why it is implicitly typecasted to float which can hold only 4 bytes rather than double which can hold 8 bytes.Why it is not considered as narrowing ?

And which primitive types will be implicitly converted to char ?

RamValli
  • 4,389
  • 2
  • 33
  • 45
  • 1
    In most of today's architectures, long doesn't hold 64 bits, it holds 32, a long long holds 64! – trumpetlicks Feb 27 '14 at 11:42
  • 1
    @trumpetlicks: Not in Java, where `long` is explicitly defined as *always* being 64 bits. – Jon Skeet Feb 27 '14 at 11:42
  • It's not clear what this question means. What "hierarchy for implicit conversion"? What *exactly* are you talking about? Spec references would really help here. – Jon Skeet Feb 27 '14 at 11:43
  • @trumpetlicks Java is not machine/architecture dependent (behavior, not performance) – amit Feb 27 '14 at 11:43
  • @JonSkeet - apologies, didn't see the "java" in the keywords :-) – trumpetlicks Feb 27 '14 at 11:46
  • possible duplicate of [Java Why is converting a long (64) to float (32) considered widening?](http://stackoverflow.com/questions/15229323/java-why-is-converting-a-long-64-to-float-32-considered-widening) – Floris Velleman Feb 27 '14 at 11:48

2 Answers2

4

It's not about how many bits of data are used. It's about the scale that can be represented.

From JLS section 5.1.2 (widening primitive conversions):

A widening primitive conversion does not lose information about the overall magnitude of a numeric value.

...

A widening conversion of an int or a long value to float, or of a long value to double, may result in loss of precision - that is, the result may lose some of the least significant bits of the value. In this case, the resulting floating-point value will be a correctly rounded version of the integer value, using IEEE 754 round-to-nearest mode (§4.2.4).

The range of long is much smaller than the range of float, but with a fixed precision of 1. The precision of float varies across the range, in terms of absolute value. In other words, no long is outside the range of float, but there are long values which can't be precisely represented as float values.

Moving to double wouldn't help this - there are long values which can't be precisely represented as double, either.

Community
  • 1
  • 1
Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
0

Just because long takes 8 bytes and float is only 4 bytes. How Java accommodates this 8 bytes stuff into 4 bytes? There will be loss of data. Isn’t it?

Conversion from long(8 bytes) to float(4 bytes) is implicit because float save values in the form of exponents.

Float store values in the form of exponents which means 2345678 will be stored as 2.345678E6, where E6 stands for 10 to the power of 6

So when we store a long value which ofcourse cannot be stored in a float, JVM converts it into exponential form and then stores it. Say, if we want to store a long value of 1234567891234 in a float, then it will first be converted into an exponential form like this: 1.234567891234E12 and hence this made it possible to store the value in a float variable which is really done implicitly.

Hold on ! There is still few things that you may have noticed. What about the precision? A Float has precision of 6-7 significant digits after decimal? I am still loosing data.

Here comes one more concept from data storage. The JVM doesn’t cares about loss of precision. It only cares about loss of magnitude. In the above example, 1 is magnitude and the digits after the decimal is the precision.