0

In the source of Integer of Java why use q = (i * 52429) >>> (16+3) rather than q=i / 10? for speed?

static void getChars(int i, int index, char[] buf) {
        int q, r;
        int charPos = index;
        char sign = 0;

        if (i < 0) {
            sign = '-';
            i = -i;
        }
        while (i >= 65536) {
            q = i / 100;
            r = i - ((q << 6) + (q << 5) + (q << 2));
            i = q; 
            buf [--charPos] = DigitOnes[r];
            buf [--charPos] = DigitTens[r];
        }

        // Fall thru to fast mode for smaller numbers
        // assert(i <= 65536, i);
        for (;;) {
            q = (i * 52429) >>> (16+3);  
            r = i - ((q << 3) + (q << 1));  
            buf [--charPos] = digits [r];
            i = q;
            if (i == 0) break;
        }
        if (sign != 0) {
            buf [--charPos] = sign;
        }
    }
user207421
  • 305,947
  • 44
  • 307
  • 483
Simon Teo
  • 1
  • 2
  • Are you asking why is this code faster than dividing by 10? – Eran Apr 22 '19 at 08:22
  • How did you measure the time? I hope with some decent benchmarking framework and not manually with `System.nanoTime()` etc, else you interpret the results of the measurements wrong and should read on how to make microbenchmarks in java. – Zabuzard Apr 22 '19 at 08:41
  • Much of the bit-twiddling code in Java comes from the book [Hacker's Delight](https://www.amazon.com/Hackers-Delight-Edition-Henry-Warren/dp/0321842685). The reasons why this is faster are explained in that book. – RealSkeptic Apr 22 '19 at 08:53
  • You are looking at the obsolete source code. There is a normal [division by 10](http://hg.openjdk.java.net/jdk9/jdk9/jdk/file/65464a307408/src/java.base/share/classes/java/lang/Integer.java#l504) in JDK 9 and beyond. See [JDK-8136500](https://bugs.openjdk.java.net/browse/JDK-8136500) for details. – apangin Apr 22 '19 at 09:45
  • It should say assert(i < 65536, i); –  Jun 30 '20 at 11:30

0 Answers0