On 11/14/2013 6:31 PM, Eric Sosman wrote:
As a more concrete example,
static final double FOO = 17.316;
static final double BAR = 8.658;
int i = FOO / BAR; // Should javac be silent here?
Neither the numerator nor the denominator can be represented
exactly as stated, yet the quotient is (probably; cook up your
own numbers if mine are faulty) exactly 2.0. Would it be a
good idea to let this construct slide through unremarked? Or
should javac acknowledge the inherent imprecisions in the
operations leading to the exactly-integral result?
In this case it's pretty clear that the error should be signaled since we have a floating point expression that involves computations where roundoff'scould do weird things:
Consider the case when we use FOO = 3.3 and BAR = 1.1. Then the value of
(int) (FOO/BAR) == 2
and I certainly wouldn't want to have a language where
int i = 3.3/1.1;
gives a different result than
double x = 3.3;
double y = 1.1;
int i = x/y;
When the integer value of the ration is a power of 2, then the internal floating point representations will differ only in the exponent, so you're likely get 'correct' values when you do the computation, but for all other integer ratios the actual value that a proper Java program would computer will often differ from the 'correct' value. And even for powers of two one isgoing to run into problems if denormalized floats or doubles are being used.
If we exclude expressions there would be still hard cases:
E.g., if we were allowing
int i = 2.0;
presumably we'd also want to allow
int i = 1.234E3; // = 1234)
but then you might be surprised to get an error for the equivalent
int i = 1.2345E3; // = 1234.5
which doesn't really look very differnt.
And what would one do with:
int i = 123456789.f;
which seems like a normal integer, but since we've gone beyond the precision of floats we'd find that
float f = 123456789.f;
int i = (int) f;
yields
i == 123456792
We wouldn't run into this when converting doubles to ints, but a similar problem occurs for doubles to longs.
So any relaxation of the rule that there is a loss-of-precision error in converting floating point values to integral values would have to be either arbitrarily limited (say to |integers| < 100) or hedged with lots of caveats.. Having a simple rule that you need to signal such a conversion with a cast seems like a reasonable choice.
Personally I'd have preferred that Java be fully consistent here and not have the exception for operators like +=
double x = 1.;
int i = 0;
i += x; // is legal
but I believe that exception is essentially required by the (imho) folly ofautomatic promotion of bytes, shorts and chars to ints.
Regards,
Tom McGlynn