I am interested in understanding the maximum number of fractional decimal digits required for exact division.
The Java BigDecimal implementation states (and implements):
If the quotient this/divisor has a terminating decimal
expansion, the expansion can have no more than
(a.precision() + ceil(10*b.precision)/3)
digits.
There is a typo/parenthesis error in the Java BigDecimal source comment.
It should read
(a.precision() + ceil(10*b.precision/3))
In this context precision is used as in computer representations of floating point numbers (e.g. IEEE Standard for Floating-Point Arithmetic 754-2008). It can be thought of as the number of digits in the significand/coefficient/mantissa s when a terminating decimal is written in base 10 scientific notation s * 10e where s has been normalized to remove all leading and trailing zeros.
Here is a snippet of the code in question:
/* * If the quotient this/divisor has a terminating decimal * expansion, the expansion can have no more than * (a.precision() + ceil(10*b.precision)/3) digits. * Therefore, create a MathContext object with this * precision and do a divide with the UNNECESSARY rounding * mode. */ MathContext mc = new MathContext( (int)Math.min(this.precision() + (long)Math.ceil(10.0*divisor.precision()/3.0), Integer.MAX_VALUE), RoundingMode.UNNECESSARY); BigDecimal quotient; try { quotient = this.divide(divisor, mc); } catch (ArithmeticException e) { throw new ArithmeticException("Non-terminating decimal expansion; " + "no exact representable decimal result."); }
This links to the BigDecimal source code:
https://github.com/frohoff/jdk8u-dev-jdk/blob/da0da73ab82ed714dc5be94acd2f0d00fbdfe2e9/src/share/classes/java/math/BigDecimal.java#L1674
I found a reference to Java BigDecimal in the answer provided by @siefca to
How to estimate the number of decimal places required for a division?
but, there is no explanation as to how it is derived.
Q: How is this formula for the maximum number of digits in an exact decimal division derived?
Best Answer
To keep the formulas a little more concise, let $n$ be the precision of the numerator, $d$ the precision of the denominator. The formula in the BigDecimal implementation that bounds the precision of the quotient can then be written $$ n + \left\lceil \frac{10d}{3} \right\rceil.$$
Note that the denominator can be multiplied by a power of $10$ to produce an integer. That integer can have only factors of some power of $2$ and some power of $5$, since otherwise we get a non-terminating decimal fraction, which is an error. Moreover, if we can pair up any factor of $2$ with any factor of $5$, they form a factor of $10,$ which does not contribute to the precision of the number. So the denominator is either $2^x \times 10^y$ or $5^x \times 10^y$ or simply $10^y$ for some positive integer $x$ and some integer $y$. (By allowing $y$ to be negative, we also account for any decimal fraction in the original denominator.)
Denominators of the form $10^y$ lead to quotients with $n$ digits of precision, so that case is dealt with easily.
Now note that each of the $x$ factors of $2$ in $2^x \times 10^y$ or $5$ in $5^x \times 10^y$ adds exactly one digit of precision (and no more) on the right-hand end of the numerator during division:
\begin{align} \frac{9999}{2} &= 4999.5 & \frac{9999}{5} &= 1999.8 \\ \frac{9999}{2^2} &= 2499.75 & \frac{9999}{5^2} &= \phantom{0}399.96 \\ \frac{9999}{2^3} &= 1249.875 & \frac{9999}{5^3} &= \phantom{00}79.992 \end{align}
So an upper bound on the number of digits of the quotient is simply $n + x.$
But the formula assumes we know $d,$ not $x.$ What is the upper bound of $x$ in terms of a known value of $d$? It's simply the exponent of the largest power of either $2$ or $5$ that you can write with $d$ digits of precision. But the exponent of that power of $2$ will always be greater than the exponent of that power of $5$. So the question is really just what power of $2$ can be written with $d$ digits of precision.
In general, for $x > 0,$ to write $2^x$ takes $d = \lceil x\log_{10}(2) \rceil = x\log_{10}(2) + f$ digits, where $0\leq f < 1.$ Solving for $x,$
$$ x = \frac{d - f}{\log_{10}(2)} \leq \frac{d}{\log_{10}(2)} < \frac{d}{0.3} = \frac{10d}{3} \leq \left\lceil\frac{10d}{3} \right\rceil $$ since $\log_{10}(2) > 0.3.$ And so $n + x \leq n + \left\lceil {10d/3} \right\rceil,$ and since $n + x$ is an upper bound on the precision of the quotient, so is $n + \left\lceil {10d/3} \right\rceil.$ That proves the correctness of the formula.
But the formula is not a particularly tight upper bound on the precision of the quotient. There is the substitution of $0.3$ for $\log_{10}$, which hardly ever will make a difference except for very large denominators (and not much difference then). There is also the fact that since $x \leq {d/\log_{10}(2)}$ and $x$ is an integer, by definition $x \leq \left\lfloor {d/\log_{10}(2)} \right\rfloor.$ And since $d/\log_{10}(2)$ is never an integer, that means the formula always gives an answer at least $1$ greater than required. Since $\log_{10}(2) > 0.301,$ a slightly tighter bound would be
$$ n + \left\lfloor \frac{d}{0.301} \right\rfloor.$$
But even that is not what makes the BigDecimal formula such a loose bound. A larger effect is due to the fact that when you repeatedly divide a number by $2,$ every third or fourth division removes one digit of precision from the left side of the number. It turns out that instead of adding $x$ digits of precision to the numerator by dividing it by $2^x,$ we add something more like $0.7 x$ digits of precision.
Another way to think about this is that dividing by $2^x$ is the same as multiplying by $5^x$ and then dividing by $10^x.$ Dividing by $10^x$ doesn't change the precision, but the multiplication by $5^x$ potentially adds as many digits of precision as the precision of $5^x,$ which is $\lceil x\log_{10}(5) \rceil.$ Since $x \leq \left\lfloor {d/\log_{10}(2)} \right\rfloor,$ this means the precision of the quotient can be at most
$$ n + \left\lceil\left\lfloor\frac{d}{\log_{10}(2)}\right\rfloor \log_{10}(5)\right\rceil \leq n + \left\lceil\frac{\log_{10}(5)}{\log_{10}(2)}d \right\rceil \leq n + \left\lceil 2.322 d \right\rceil. $$
So an alternative formulation is that there are at most $n + \left\lceil 2.322 d \right\rceil$ digits in the quotient. This grows slower than the formula that was used.