1

I 've got some double numbers like :3.0 3.1 4.0 5.2,etc.

Can I Judge if the number ends with .0 like 3.0 and 4.0?

Is there a best way to do so ?

PS:I converted them to String type,however I don't think it's the best way.

    double i = 3.0;
    String d = i + "";
    return d.endsWith(".0");
Prasad
  • 1,188
  • 3
  • 11
  • 29
Johnny Chen
  • 2,025
  • 1
  • 18
  • 27

3 Answers3

7

You can do something like this.

double d = 10.09;
System.out.println(d == Math.floor(d));
// True if it ends with 0, else false

// If you want to return the boolean result
return d == Math.floor(d);

Note: It'll work till the value is double d = 10.000000000000001;. Another 0 in the decimal would end up giving the wrong result(all thanks to the floating point representation inaccuracy).

Community
  • 1
  • 1
Rahul
  • 44,383
  • 11
  • 84
  • 103
  • I'm not completely sure but this may fall over due to double accuracy issues. If d = 10.0 then the actual binary representation will be nearly but not exactly 10. If the representation is actually just under 10 then the floor operation may pull it down to 9 and fail. It would also potentially fail for negative numbers. – Tim B Dec 12 '13 at 10:56
  • @TimB - Can you give a possible example which may fail. I'd love to build up on that and fix the answer, if required! :) – Rahul Dec 12 '13 at 11:01
  • As I understand it floating point inaccuracy can go down as well as up. This means that if you (for example) entered 10.0 you may actually end up with 9.999999999999999999999999999999764 (random numbers picked for example). That means Math.floor(10.0) would come back with (9.0) unless Math.floor() has special logic within it to detect those cases. I'm not sure if it does although it may. – Tim B Dec 12 '13 at 11:10
  • @TimB - When I tried using the same for `double d = 10.0d;`, it worked fine, giving the result `true`. So I guess, `Math.floor` works fine in most of the cases, but there may be certain very very rare edge cases, which I don't know. as of now. – Rahul Dec 12 '13 at 11:12
  • As said 10.0 was a number picked at random, I don't actually know off hand which numbers error down and which up and don't have time to write a program to find out (Google didnt give me a list). Safest test would be to run it on a for loop of every integer from -1000 to +1000 and see if they all work. – Tim B Dec 12 '13 at 11:14
2

This could be done like this:

double d = 3.0;
System.out.println("Ends with a '.0': " + ((d * 10) % 10 == 0));

If you are setting the value like this:

double d = 2.9999999999999999;

set a breakpoint on this line, step over and look for the value of d. You will recognize that the value is already 3.0.
So any conversion afterwards will be using the value 3.0. That's why you can't avoid this problem using double variables.

bobbel
  • 3,327
  • 2
  • 26
  • 43
  • I think this is a better solution as it removes the double accuracy issues and supports any number of decimal places by changing the *10 appropriately. – Tim B Dec 12 '13 at 10:58
  • Honestly... This **won't** remove the double accuracy either... The behavior is quite the same... – bobbel Dec 12 '13 at 10:59
  • Yes, you may need to force a conversion to integer before doing the %10 - the integer conversion will round the double appropriately. – Tim B Dec 12 '13 at 11:01
  • Converting the double value to an integer value doesn't solve the problem either. You can't really get rid of this in a proper way. Even by doing something like `("" + doubleValue).endsWith(".0")` you will get `3.0` isntead of `2.99999999999999`. – bobbel Dec 12 '13 at 13:12
0
public static void main(String[]args) {
    double d = 101.3;
    d.toString().endsWith(".0") ? System.out.println("Ends with 0"): System.out.println("Not ends with 0");
}
Rahul
  • 44,383
  • 11
  • 84
  • 103