There are two concepts involved here:
- A machine precision unit:
Double.ulp()
- A machine precision for a given
double d
: Double.ulp(d)
If you call Double.ulp()
you will obtain the machine precision unit, which is the precision you can expect from a certain hardware platform... whatever this definition might be!
If you call Double.ulp(d)
, you will get the machine precision for double d
. In other words, every double d
has its specific precision. This is more useful than the previous paragraph.
You must take particular attention to detail when you are performing iterations which involve calculations in cascade, i.e.: when results from the previous calculations are employed in the current calculation. This is because errors accumulate in these situations and may end up, in certain circumstances, delivering results which are way off the true value they should deliver. In certain circumstances, the size of the accumulated error may even be greater than the true value. See some disastrous examples here.
In certain business domains, numerical computation errors are simply not acceptable. Depending on the business domain, its regulations, requirements and characteristics, you must take alternative approaches for the simplistic choice of employing floating point arithmetic (i.e: doubles
or floats
).
In the case of Finance for example, never ever use floating point arithmetic. Never ever use doubles
or floats
when you are dealing with money. Never. Period. You can employ BigDecimal or fixed point arithmetic, depending on circumstances.
In the specific case of processing stock prices, you know that prices have always 5 digits of precision and, in this case, fixed point arithmetic is plenty enough and also delivers the maximum performance you can possibly obtain, which is a very strong and common requirement in this business domain.
If the business domain really requires numerical computations, you must in this case make sure you keep error propagation under your strict and very careful control. This is a long subject, there are a number of techniques, and very frequently developers overlook the problem simply believing that there's a single magic call to a method which does all the hard work for them. No, it doesn't. You have to do your research, do your homework and do all the hard work necessary in order to make sure you keep errors under control. You need to understand exactly what is going on with the numerical algorithms you've implemented.