2

I'm rewriting some scientific code that someone else wrote a while back, and throughout the code constants are always declared as:

final double value = 2.0000000000D;

with an apparently arbitrary length of supposedly significant digits attached to it. I'm 95% sure that declaring variables in this way actually does nothing, and that setting the value to:

double value = 2.0;

would be exactly the same. But just to be sure, I'm asking SO, does declaring a constant in this fashion make any (meaningful) difference, or is this likely just a relic from another language where it might have made a difference?

EDIT: In response to an answer below: Yes, I verified that the answer is the same in this particular instance before asking this question. Maybe I should have been more specific. Is there ever an instance, where we would expect that adding additional "significant" digits would in fact return a different number? I suppose it's possible if we get to really large or really small values where floating point numbers start to have resolution issues?

2 Answers2

3

In your example it makes no difference. You can verify this like,

final double value1 = 2.0000000000D;
double value2 = 2.0;
System.out.println(value1 == value2);

Which outputs

true

It's also legal to use double value2 = 2.;

Elliott Frisch
  • 198,278
  • 20
  • 158
  • 249
  • Yes, I verified that as well before asking this question. Maybe I should have been more specific. Is there ever an instance, where we would expect that not to be the case? – user1337732 Mar 12 '16 at 22:17
  • 1
    or just double value=2; :) – Gee Bee Mar 12 '16 at 22:17
  • `System.out.println(0.05 + 0.05 + 0.05);` Java follows [IEEE 754](https://en.wikipedia.org/wiki/IEEE_floating_point), there are some numbers that aren't precisely representable in binary (just as in decimal, `1/3`). – Elliott Frisch Mar 12 '16 at 22:18
  • @GeeBee True, a widening conversion would also work. But `2.` is a `double` (without widening). – Elliott Frisch Mar 12 '16 at 22:20
0

Uh, there is definitely some misunderstanding in that legacy code.

double value=2 

works well.

It is pointless to set decimals to zero, and it is likely errorneous to set a double with decimals. For example,

double preciseNumber=3.1415926535897932384626433832795028;

is bogous:

  • the developer assumes that double does have an arbitrary decimal precision - but that is not the case
  • the developer assumes that the double will store the identical decimal number as intended - but that's not the case since it is stored in binary fractions instead of decimal fractions.

For precise calculations, consider using BigDecimal (and pass the initial value in String to ensure that no decimals get lost).

Gee Bee
  • 1,794
  • 15
  • 17
  • BigDecimal is no more capable of exact representation of pi than double. – Patricia Shanahan Mar 13 '16 at 00:41
  • Good catch :) but you got the point: once it is having endless decimals, it can be precisely represented in BigDecimal. However it is very likely become an endless binary fractional, hence double can not represent decimal fractions always correctly. – Gee Bee Mar 13 '16 at 00:46
  • Ever tried to exactly represent one third in BigDecimal? You hit exactly the same problem as representing one tenth in double. – Patricia Shanahan Mar 13 '16 at 00:51
  • @Patricia, I understand your point, and I can see that binary and decimal fractions are all problematic. However it is not the *same* problem. I as a human can clearly see that I can't write a correct value for 1/3, so I'll settle with some digits: 0.3333333333333333. In case of the double, I am sure I wrote double d=0.1. I expect that if I sum this up 10 times, I will get 10, but instead I will get 9.9999999999999999. – Gee Bee Mar 13 '16 at 01:05
  • I created `new BigDecimal("0.3333333333333333")`, added three copies of itself, and got output 0.9999999999999999. It does not matter. You cannot measure any real world quantity with anything like the precision of a double. – Patricia Shanahan Mar 13 '16 at 02:31
  • Patricia, you're perfectly right, you can measure any quantity with a double. Since your 0.33333 is having a fixed decimal precision, you will get 0.99999, pure math. However, if you do further calculations with doubles - such as summing up double value of 0.1 10 times - you'll introduce a new inaccuracy which is not expected. Therefore using double for example in monetary calculations is unadvised. There are cases when you can not work with a double. See also http://stackoverflow.com/questions/3413448/double-vs-bigdecimal – Gee Bee Mar 13 '16 at 20:41
  • Money is one of the few cases in which short terminating decimal fractions really are special, and therefore I prefer BigDecimal. I don't object to using it when it makes sense, just to pushing it where double would be just as good and result in simpler, clearer code. – Patricia Shanahan Mar 13 '16 at 20:43
  • Totally agreed, Patricia! I used to work with over-engineered software, where all numeric types were represented as BigDecimal even if it was a simple numeric identifier. Baaah :) – Gee Bee Mar 13 '16 at 21:00