Integer literals are per default of type "int", fine.
Floating point literals are per default type "double", fine.
For initializers, integer arguments are automatically cast down:
byte b=42;
Why not for floats?
float f=4.2; --> error: possible loss of precision.
Of course I know, that I can add an "f", to solve this, but why?
Why doesn't javac follow the same reasons as for the integral case?
Hi,
Andreas Leitgeb schrieb:
> Integer literals are per default of type "int", fine.
> Floating point literals are per default type "double", fine.
[quoted text clipped - 6 lines]
> Of course I know, that I can add an "f", to solve this, but why?
> Why doesn't javac follow the same reasons as for the integral case?
the message tells you why ;)
If you convert the int value of 42 to an byte value, its still exactly
42. Bytes and integers are natural numbers.
If you convert the double value of 4.2 to a float, you might loose
precision. If you look at the bit representation of a float and a
double, the double value is more precise (double precision). Double and
float are only approximations to numbers.
To overstate: the double value is 4.2000000000 and the float value could
be 4.199999999 due to the missing precision. The actual differences
would be much smaller, I think. That simply because there might be no
float representation that "exactly" hits 4.2, whereas a double
representation does.
Google for some reading on that topic, if you like. You should fing loads.
Regards,
Tobi
Andreas Leitgeb - 13 Nov 2006 15:27 GMT
> Andreas Leitgeb schrieb:
>> For initializers, integer arguments are automatically cast down:
>> byte b=42;
> If you convert the int value of 42 to an byte value, its still exactly
> 42. Bytes and integers are natural numbers.
note further, that
byte b;
b=42;
does, however, fail with the "possible loss of precision" message.
So, if javac was intelligent enough to recognize the constant 42
as fitting into a byte, it could also see it fits into a byte
at a later time.
It is not that intelligent, but it suppresses the error
specifically for initialization.
My question was: why doesn't it also suppress the warning
for floats as well, and implicitly assume a trailing "f"
if it is clear that the literal is exclusively used to
initialize a float-typed variable.
> If you convert the double value of 4.2 to a float, you might loose
> precision.
Of course, 4.2 was not an ideal example, but the result isn't
different, if we use 42. or 42.5 which are *exactly*
represened in any base-2 floating point math. both float and double
can carry 42.5 lossless.
> Google for some reading on that topic, if you like. You should fing loads.
I failed to come up with concise keywords for this problem.
googling on: java float initializer gives me gobs of unrelated
hits.
Tobias Schröer - 13 Nov 2006 15:48 GMT
Andreas Leitgeb schrieb:
>>Andreas Leitgeb schrieb:
>>[..]
[quoted text clipped - 3 lines]
> googling on: java float initializer gives me gobs of unrelated
> hits.
Try 'java "loss of precision"'. I only had a brief reading but there
seemed to be some useful things. Have you searched the java specs?
Andreas Leitgeb - 13 Nov 2006 16:57 GMT
> Try 'java "loss of precision"'. I only had a brief reading but there
> seemed to be some useful things. Have you searched the java specs?
That gave me more relevant hits, thanks, but still these hits
only state how it is, and I knew that (I mentioned with my first
question, that I knew I could fix it by appending an "f")
My question was less of type:
"how can it be done",
but instead:
"Why was it specified such?"
And my question was also specifically addressing the
context of inititializers, where for byte,char,short
the compiler is obviously less picky/fussy/....
Patricia Shanahan - 13 Nov 2006 17:41 GMT
>> Try 'java "loss of precision"'. I only had a brief reading but there
>> seemed to be some useful things. Have you searched the java specs?
[quoted text clipped - 11 lines]
> context of inititializers, where for byte,char,short
> the compiler is obviously less picky/fussy/....
I think there are two differences to consider:
1. For e.g. byte, if the constant is within the variable's range, it is
exactly convertible. Some doubles within the float range can be
converted exactly to float, others cannot.
Moreover, casting a double literal to float does not always give the
same answer as the corresponding float literal - rounding twice can
confuse matters.
2. Probably to avoid forcing rounding twice, the language provides a
distinct, no-cast, syntax for float literals, the use of a trailing "F"
or "f". That is what should be used for maximum accuracy:
float f = 4.2F;
not
float f = (float)4.2;
which would be the analog to:
byte b = (byte)42;
Patricia
Andreas Leitgeb - 14 Nov 2006 12:39 GMT
> 2. Probably to avoid forcing rounding twice, the language provides a
> distinct, no-cast, syntax for float literals,
hmm, meanwhile it makes sense: casting from int down to
a smaller type is actually a noop, whereas casting from
double to float is indeed a "calculation"...
Thanks, I think I got it now.