6

With the following code:

Float a = 1.2;

there is an error because it takes the decimal as double value and double is a bigger datatype than float.

Now, it takes integer as default int type. So, why is the following code not giving any error?

Byte b = 20;
Cœur
  • 37,241
  • 25
  • 195
  • 267
  • I dont know why you are not understanding my question.....you said that compiler is smart enough to put 20 in byte....then why is compiler not putting 1.2 in float....my simple ques was ...i read that in java all decimal are treated as double while all integers are treated as int by default......then when i m assigning 20 to a byte why is it not giving any error... – Crasher Hacs Aug 29 '15 at 10:28

2 Answers2

7

The compiler is smart enough to figure out that the bit representation of 20 (an int value) can fit into a byte with no loss of data. From the Java Language Specification §5.1.3:

A narrowing primitive conversion from double to float is governed by the IEEE 754 rounding rules (§4.2.4). This conversion can lose precision, but also lose range, resulting in a float zero from a nonzero double and a float infinity from a finite double. A double NaN is converted to a float NaN and a double infinity is converted to the same-signed float infinity.

A narrowing conversion of a signed integer to an integral type T simply discards all but the n lowest order bits, where n is the number of bits used to represent type T. In addition to a possible loss of information about the magnitude of the numeric value, this may cause the sign of the resulting value to differ from the sign of the input value.

See also this thread.

Community
  • 1
  • 1
Ted Hopp
  • 232,168
  • 48
  • 399
  • 521
  • The bit representation of 200 also fits into the 8 bits of byte without loss of data. What's important is that the same numeric value can be represented in the target type. – Joni Aug 27 '15 at 17:51
  • @Joni - Well, yes and no. Because `byte` values are signed in Java, "fit into" really means "fit into 7 bits", not 8 bits. The bit pattern of 200 is `1100 1000`. When this is put into an 8-bit `byte` value, it represents the value -56, not the value 200. That is because the representation of 200 overflows into the sign bit of a `byte`. You are absolutely right about the important thing being the representation of the same value. – Ted Hopp Aug 27 '15 at 18:08
1

There are no implicit narrowing conversions in general - constant expressions are the only exception, and they are explicitly allowed by JLS 5.2:

In addition, if the expression is a constant expression (§15.28) of type byte, short, char, or int:

* 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.

There is no mention of implicit narrowing conversions being allowed for floating point numbers, so they are forbidden as per the general rule.

Joni
  • 108,737
  • 14
  • 143
  • 193
  • +1 for citing the part of the spec that specifies why `float`/`double` behaves differently than `byte`/`int`. (Besides the narrowing, there is loss of information in OP's specific example, because 1.2 is not exactly representable in floating point. However, the compiler would complain even if the value were 1.0 or something else exactly representable as a `float`.) – Ted Hopp Aug 27 '15 at 18:33