5
char c1 = 123; //Compiles fine
char c2 = 123456; //Error: cannot convert from int to char

Java is smart enough to determine whether an integer is small enough to be converted to a character. Why is it not able to convert very small floating point literals to a float?. For example:

float f1 = 0.3; //Error: cannot convert from double to float
float f2 = 0.3f; //Compiles fine

char c = some integer literal might compile but float f = some floating point literal will never compile. Why?

PS: I know that a floating point literal is treated as a double by default

Piyush Saravagi
  • 369
  • 2
  • 10
  • possible duplicate of [Java: Why do you need to specify a 'f" in a float literal?](http://stackoverflow.com/questions/14102955/java-why-do-you-need-to-specify-a-f-in-a-float-literal) – RealSkeptic Jun 27 '15 at 19:18
  • My question is not about the 'f' in floating point literals. It is about how a larger data type is converted to a smaller data type without any problem in one case (int to char, 32 bits to 16 bits) while it gives a compilation error in the other case (double to float, 64 bits to 32 bits). The literal is small enough to be fit the float variable just as the int was small enough to fit the char.@RealSkeptic – Piyush Saravagi Jun 27 '15 at 19:33
  • The answer is nevertheless in that question - best answer is not the accepted one, though. – RealSkeptic Jun 27 '15 at 19:36

1 Answers1

7

0.3 is treated as a double, so its binary representation takes 64 bits and it can't fit into a float without possible loss of precision, so you can't assign it to a float variable without an explicit cast.

On the other hand, if you assign to a char variable an int literal within the range of the char type (for example 123), there's no loss of data.

Both of the assignments (int to char variable and double to float variable) require a narrowing primitive conversion.

JLS 5.2 says

A narrowing primitive conversion may be used if the type of the variable is byte, short, or char, and the value of the constant expression is representable in the type of the variable.

Eran
  • 387,369
  • 54
  • 702
  • 768
  • 3
    I would add that `0.3` can't be exactly represented in binary floating-point with *any* level of precision. – Sam Estep Jun 27 '15 at 19:18
  • 1
    An integer, no matter how small, will always be represented by 32 bits while a character is represented by 16 bits. So is there not a possible loss of precision here as well?. Just like in case of floats and doubles? – Piyush Saravagi Jun 27 '15 at 19:23
  • 1
    @PiyushSaravagi See the quote I added from the JLS. Any int between 0 and 2^16-1 can be assigned to a char variable without any loss of information, since the top 16 bits of the int will contain 0s so they can be discarded without losing any information. – Eran Jun 27 '15 at 19:26
  • 2
    @RedRoboHood That may be true (I didn't check), but even if it wasn't it won't make a difference. `float d = 0.5;` will fail to compile too, even though 0.5 can be represented exactly in both float and double precision. – Eran Jun 27 '15 at 19:34
  • 1
    @Eran No disagreement there; it was just something interesting that I thought might be worth mentioning. – Sam Estep Jun 27 '15 at 19:35