2

I have a collection of BigIntegers and am trying to get the number of digits in each integral number. For the sake of brevity, lets say that we are only dealing with positive numbers. We are looking at numbers with over 1000 digits.

The following are the ways I have thought of.

  1. length of a string representation (will require a bunch of memory)

  2. modulo 10 approach (slow)

  3. an asanine idea (included for sake of thoroughness, since scalability of this approach is not great)

    if (i >= 100000000) {
        i /= 100000000;
        n += 8;
    }
    if (i >= 10000) {
        i /= 10000;
        n += 4;
    }
    if (i >= 100) {
        i /= 100;
        n += 2;
    }
    if (i >= 10) {
        i /= 10;
        n += 1;
    }
    
  4. logarithms (which I find rather friendly) (credits go to [this answer])

    int blex = val.bitLength() - 1022; // any value in 60..1023 is ok
    if (blex > 0)
        val = val.shiftRight(blex);
    double res = Math.log10(val.doubleValue());
    return blex > 0 ? res + blex * LOG2 : res;
    
  5. This is an idea I have but want to test the validity of before coding; say I have some number x. Try to divide by powers of 10 using concepts of (traditional or one-sided) binary search, and stop when 0 < quotient < 10. That power + 1 should be the number of digits. This would be a logarithmic solution (?).

StackOverflow did not really seem to have something solid to calculate the number of digits in any number. This accepted answer suggests a division-heavy approach that can result in a bunch of new objects being created. I was wondering if there can be a slicker solution. So, I thought this post would lead to a fruitful discussion and collaboration of ideas. Please suggest which method would work best for really large numbers.

Community
  • 1
  • 1
Debosmit Ray
  • 5,228
  • 2
  • 27
  • 43
  • have you looked at http://stackoverflow.com/a/23773083/5808727 ? – Pooya Apr 09 '16 at 07:07
  • @Pooya Yep! The `bitLength()` function being used there; I am not entirely sure of how that would play out in terms of performance; more so, in terms of accuracy (see Dariusz's answer). I might be very wrong though. Hence this post. :) – Debosmit Ray Apr 09 '16 at 07:09
  • I think it worth benchmarking couple of these answers on the same system – Pooya Apr 09 '16 at 07:11
  • I'll do benchmarks on all of these and post it as an answer soon – Debosmit Ray Apr 09 '16 at 07:14
  • each 10-bit limb corresponds to about 3 decimal digits, so you can count the number of bits (of the full limb) and multiply it 3/10 then add the number of digits in the last limb – phuclv Apr 09 '16 at 07:14
  • @LưuVĩnhPhúc That is an interesting approach. Wouldn't that result in some loss of accuracy? – Debosmit Ray Apr 09 '16 at 07:16
  • Yes the actual value might be a little smaller so it needs some correction. How to calculate that correction is out of my ability, maybe some mathematician can help. I've seen a function to convert floating-point to string uses this way to get the number of digits – phuclv Apr 09 '16 at 07:18
  • @LưuVĩnhPhúc I see. Thanks for the note. I will look into it and update. – Debosmit Ray Apr 09 '16 at 07:20
  • this may help http://www.exploringbinary.com/how-the-positive-powers-of-ten-and-two-are-interleaved/ – phuclv Apr 09 '16 at 08:33

0 Answers0