38
Utilities.getDistance(uni, enemyuni) <= uni.getAttackRange()

Utilities.getDistance returns double and getAttackRange returns int. The above code is part of an if statement and it needs to be true. So is the comparison valid?

Thanks

Tasos
  • 1,575
  • 5
  • 18
  • 44
  • Did you try it? Did it work? – Rohit Jain Nov 08 '12 at 20:26
  • How can I test if it's valid. Compiler accepts it but I can't know if the actual numeric values are indeed compared. – Tasos Nov 08 '12 at 20:29
  • 1
    Have you tried it your self?? A simple test in java code could have sufficed. check my answer for the same – Fr_nkenstien Nov 08 '12 at 20:31
  • 1
    It is valid, but you may get interesting results in edge cases if you don't specify a precision on the double... – PinnyM Nov 08 '12 at 20:31
  • @Vineet Verma yea I didn't know I could actually print the result of a logical statement, I'm kinda 2 days old in Java. Thanks a lot though – Tasos Nov 08 '12 at 20:33
  • 2
    With the caveat from @PinnyM, I should point out that converting `int` to `double` is lossless, but promoting `long` to `double` is lossy. That is, there are some values of type `long` for which no exact value of type `double` exists, so the conversion will lose information. Not so with `int` to `double`, but also true with `int` to `float`. – Nathan Ryan Nov 08 '12 at 20:36
  • @Crone: This is generally true, regardless of language, when converting a value of an integer type to a value of a floating-point type, when the number of bits required by the integer type is greater than the number of bits required by the mantissa of the floating-point type. – Nathan Ryan Nov 08 '12 at 20:54
  • @NathanD.Ryan Could you please point out one specific `long` literal for which `System.out.println(l == (double)l)` prints `false`? I can't seem to find one. – Marko Topolnik Nov 08 '12 at 21:07
  • Your statement will always print true, because `l` is being promoted to a value of type `long` on both sides of the equality. However, `System.out.println(Long.MAX_VALUE)` will print something different than `System.out.println((double)Long.MAX_VALUE)`. – Nathan Ryan Nov 08 '12 at 21:12
  • @MarkoTopolnik: Sorry, I meant to say that `l` is being promoted to a value of type *`double`* on both sides of the equality (in accordance with the rules of binary numeric promotion). – Nathan Ryan Nov 08 '12 at 21:19
  • 1
    @NathanD.Ryan Yes, I was actually testing with the correct stuff, but simplified it the wrong way for the comment. In the meantime I fixed another minor issue with my code, so here is the smallest long that fails: `long l = (1L << 53) + 1; double d = l; System.out.println((long)d == l);` – Marko Topolnik Nov 08 '12 at 21:22

6 Answers6

76

Yes, it's valid - it will promote the int to a double before performing the comparison.

See JLS section 15.20.1 (Numerical Comparison Operators) which links to JLS section 5.6.2 (Binary Numeric Promotion).

From the latter:

Widening primitive conversion (§5.1.2) is applied to convert either or both operands as specified by the following rules:

  • If either operand is of type double, the other is converted to double.

  • ...

Community
  • 1
  • 1
Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
8

When performing operations (including comparisons) with two different numerical types, Java will perform an implicit widening conversion. This means that when you compare a double with an int, the int is converted to a double so that Java can then compare the values as two doubles. So the short answer is yes, comparing an int and a double is valid, with a caveat.

The problem is that that you should not compare two floating-piont values for equality using ==, <=, or >= operators because of possible errors in precision. Also, you need to be careful about the special values which a double can take: NaN, POSITIVE_INFINITY, and NEGATIVE_INFINITY. I strongly suggest you do some research and learn about these problems when comparing doubles.

Code-Apprentice
  • 81,660
  • 23
  • 145
  • 268
  • Funny thing is this is my professors code. But yea I will investigate the subject now – Tasos Nov 08 '12 at 20:35
  • @Crone For a school assignment, you probably can ignore these edge cases, but you should still know about them. Choosing to ignore them is preferrably than complete ignorance. – Code-Apprentice Nov 08 '12 at 20:39
  • 1
    I don't see anything wrong with comparing a `double` with `<=` or `>=` against an `int`. Only exact equality might be questionable. – Marko Topolnik Nov 08 '12 at 20:43
  • @MarkoTopolnik <= or >= may give undesirable results in some cases, just like == does. – Code-Apprentice Nov 08 '12 at 20:45
  • "Some cases" is not as unpredictable as you picture it and when calculating Euclidian distance, it would be perfectly alright. – Marko Topolnik Nov 08 '12 at 20:51
  • @MarkoTopolnik Granted, it is not entirely unpredictable, just as it is not with `==`. There is plenty of information available about comparing floating point values for equality, so if the OP needs/wants more detail, they can research it further. – Code-Apprentice Nov 08 '12 at 20:55
  • Yea I can understand this is a case of way too much detail for a university code. I also completely agree with the fact that tmi can be really harmful when you start to learn a language. Thanks a lot for the input guys – Tasos Nov 08 '12 at 20:58
  • All Integers up to 2^52 are exactly represented as double. So there is no problem to compare int with double, even for equality, if you know it stores an integer, which could be not true if you operate over that variable. – Daniel Apr 10 '15 at 21:12
3

yes it is absolutely valid compare int datatype and double datatype..

int i =10;
double j= 10.0;
 if (i==j)
{
System.out.println("IT IS TRUE");
}
BRIJESH
  • 31
  • 1
2

This should be fine. In floating point operation/comparisons, if one argument is floating/double then other one being int is also promoted to the same.

Yogendra Singh
  • 33,927
  • 6
  • 63
  • 73
2

Yes it valid, and your code should work as expected without any glitch, but this is not the best practice, static code analyzers like SonarQube shows this as a "Major" "Bug",

Major Bug img from sonarQube

Major Bug description from sonarQube

so, the right way to do this can be,

Double.compare(val1,val2)==0 

if any parameter are not floating point variable, they will be promoted to floating point.

Karthik H
  • 1,267
  • 12
  • 13
0

It will be ok.

Java will simply return true of the numerical value is equal:

    int n = 10;
    double f = 10.0;
    System.out.println(f==n);

The code above prints true.

Fr_nkenstien
  • 1,923
  • 7
  • 33
  • 66