5

Given two decimal numbers, is it possible to estimate the number of decimal places required to fit the result of their division? Provided that the division yields a finite number of decimals, of course.

For example:

  • 1234.5678 / 2 = 617.2839, 4 decimal places required
  • 1234.5678 / 4 = 308.64195, 5 decimal places required
  • 1234.5678 / 8 = 154.320975, 6 decimal places required
  • 1234.5678 / 6.4 = 192.90121875, 8 decimal places required

By estimate, I don't necessarily need the exact number of decimals in the result, but a number of decimals at least equal to the required amount, so that it is guaranteed that the result fits.


What I've tried

I was able to roughly solve my problem using rational numbers & prime factorization, but this is very compute expensive. Here are the steps:

  • Take the original division: 1234.5678 / 6.4
  • Convert it to a rational number: 12345678 / 64000
  • Simplify this fraction using the GCD of the two numbers: 6172839 / 32000
  • Take the denominator: 32000
  • Compute the factors of 2 and 5 by dividing successively by these two numbers:
    32000= 28 * 53
  • (if it is found at this step that the number has other factors than 2 and 5, then stop here: the division yields an infinite number of digits)
  • Take the maximum of the two exponents: max(8,3) = 8
  • ⇒ 8 decimal places is enough to fit the result of the division.

How I came to the conclusion above

Out of all the prime numbers, only dividing by 2 and 5 yields a finite number of digits.

Each division by 10 extends the scale of the decimal number by 1 digit. Each combination of 2 and 5 yields a 10, so an extra digit.

In 2x * 5y, there are min(x,y) times 10.

Now each division by 2 or 5 can potentially (although not always) require an extra digit. So I will carefully add an extra digit for each remaining 2 or 5 factor:

Maximum required digits = min(x,y) + (x - min(x,y)) + (y - min(x,y))

Which simplifies to: x + y - min(x,y)

Which further simplifies to max(x,y).


I feel like my approach, although it works, is overly complex. The direct consequence on my software is the slowness of the algorithm.

Is there a more straightforward approach to estimating the number of decimal places required for the result of the division to fit?

Note that I've read this question: Number of decimal places to be considered in division but it didn't help.

BenMorel
  • 203
  • 2
    I don't think there is a simpler way. Good work though. – preferred_anon Jun 25 '15 at 21:27
  • I don't see why you think your algorithm is overly complex. In what context is it too slow? – Rob Arthan Jun 25 '15 at 23:22
  • @RobArthan It involves calculating the GCD, which is a recursive algorithm requiring to calculate several times the remainder of a division; then to decompose in factors 2 and 5, which requires again a number of divisions that is dependent on the size of the number. That's a lot of divisions to calculate the scale of the result of a single division! Especially for an arbitrary-size numbers library. – BenMorel Jun 26 '15 at 20:46
  • So this is about memory management in an arbitrary size arithmetic library you are designing? Why can't you allocate memory as you do the division? In any case, you need to quantify the time and space problems you are concerned about. Just saying "lots of divisions" doesn't help anybody to understand your problem. GCD is easily calculated using a loop if you find the performance of recursion worrying, but if that is the case then your problem is a computer science problem not a mathematical one. Why not use GMP? Or see how GMP does it? – Rob Arthan Jun 26 '15 at 21:31
  • @RobArthan My library does use GMP when available. This is not about memory management, but rather about clock cycles required to compute the result. Every division is compute-heavy, so if there's a cleverer way to achieve the same result with less divisions, I'll take it! If none, then my approach will be good enough, I guess. – BenMorel Jun 26 '15 at 21:43
  • But your question is about the number of decimal places required for the result of the division. Why do you need to know that in advance to achieve a fast algorithm? – Rob Arthan Jun 26 '15 at 21:56
  • Ah, you misunderstood the question, I guess. I don't need the scale to make the division faster. I need the scale so that I can allocate the number of digits of the decimal result before doing the division. Like to divide 1234.5678 / 6.4, which is 12345678 / 64000, I will actually divide 1234567800000000 / 64000 (adding 8 zeros to the numerator), so I can be sure that this division will have no remainder. The result, 19290121875, will be associated with the scale 8 to form the decimal 192.90121875. I need to compute this scale before the division, as fast as possible. – BenMorel Jun 26 '15 at 22:20
  • I apologise for my misunderstanding of your question. My reading of your question led me to think that you wanted to know how many digits to allocate to the result of a division problem. However, your last comment tells me that you what you actually wanted to know was how many digits to allocate to the result of a division problem. I'm afraid this distinction is too subtle for me. – Rob Arthan Jun 26 '15 at 22:59
  • I'm not sure how I should understand your comment? – BenMorel Jun 26 '15 at 23:27
  • I'm not sure how to make it clearer. If you ask me to divide 1234.5678 by 6.4 rounded to 2 decimals, then easy, I'll divide internally 1234567800 / 64000 and retain the quotient. If you don't hint me on the scale of the result, then I need to do some extra computation to pre-calculate how many zeros I have to add to the numerator before doing the division. And I'm trying to make this computation faster, assuming that there might be a cleverer method than mine. Hence this question. – BenMorel Jun 26 '15 at 23:35
  • Note: My final implementation is here. – BenMorel Feb 20 '19 at 08:44

1 Answers1

1

Have you tried calculating the maximum precision needed to reserve a place for the result?

Look how Java's BigDecimal does that:

https://github.com/frohoff/jdk8u-dev-jdk/blob/da0da73ab82ed714dc5be94acd2f0d00fbdfe2e9/src/share/classes/java/math/BigDecimal.java#L1674

Then the non-terminating numbers will cause an overflow of this area, so just check for this corner case during calculation and if that will happen, you can be sure it cannot be precisely expressed as decimal number.

siefca
  • 111