9

I recently learned, while converting some Java code to C#, that Java's increment operator '+=' implicitly casts to the type of LHS:

int i = 5;
long lng = 0xffffffffffffL;  //larger than Int.MAX_VALUE
i += lng;                    //allowed by Java (i==4), rejected by C#

is equivalent to: (details here)

int i = 0;
long lng = 0xffffffffffffL;
i = (int)(i + lng);

thus silently causing the opportunity for loss of magnitude.

C# is more conscientious about this at compile-time:
Cannot convert source type long to target type int.

Are there other similar situations allowed by Java?

Community
  • 1
  • 1
Cristian Diaconescu
  • 34,633
  • 32
  • 143
  • 233
  • Possibly because it's not a question about C#, it just referrs to it ?? I find it annoying (but I don't downvote) when people include the `[java]` just because they mention it in the question. – Peter Lawrey Dec 19 '12 at 10:44
  • @Peter Okay, you may have a point. I was in a very C#-y mindset when I asked the question (being neck-deep in fixing C# code that was converted from Java). Never thought of adding tags from the readers' point of view :) [C# tag removed] – Cristian Diaconescu Dec 19 '12 at 15:51
  • 2
    I am just guess here. I find it annoy when people down vote but there is no comment as to why. It's like telling you; I feel like you have done something wrong, but I am not telling you what or I don't even know what it is myself. ;) – Peter Lawrey Dec 19 '12 at 15:58
  • @Peter so... umm, why remove your answer? – Cristian Diaconescu Dec 19 '12 at 16:12
  • While it was similar in the example I gave it was not the same an implcit cast. meriton pointed out that you cannot give it value which is out of range and I noted that you cannot write `byte b = 1.0;` but you can write `b += 1.0;` – Peter Lawrey Dec 19 '12 at 16:17

1 Answers1

4

A long can be promoted to a float or double, which results in a loss of accuracy:

public static void main(String[] args) {
    float f = Long.MAX_VALUE;
    double d = Long.MAX_VALUE;

    System.out.println(Long.MAX_VALUE);
    System.out.println(f);
    System.out.println(d);

}

prints

9223372036854775807
9.223372E18
9.223372036854776E18

I suspect C# does this the same way, though.

Aside from the compound assignment operators you already mentioned, I believe those to be all cases where an implicit conversion can change the value.

meriton
  • 68,356
  • 14
  • 108
  • 175
  • Conversion from `float` to `double` may change ranking by hundreds or orders of magnitude. Given `float f=1E20; float f2=f*f; double d = 1E300;`, a comparison between `f2` and `(float)d` will correctly regard the values as indistinguishable. On the other hand, comparing `d` and `(double)f2` will indicate that `d` is *smaller* than `f2`, even though it should be 240 orders of magnitude bigger. – supercat Feb 10 '14 at 22:42
  • Your example fails to support your claim, because it uses an *explicit* conversion which can (and in this instance does) change the value. Specifically, we have `((float) d) != d` and `((double) f2) == f2`. – meriton Feb 10 '14 at 23:12