Way to get number of digits in an int?

后端 未结 30 1308
梦毁少年i
梦毁少年i 2020-11-22 17:21

Is there a neater way for getting the number of digits in an int than this method?

int numDigits = String.valueOf(1000).length();
30条回答
  •  暖寄归人
    2020-11-22 17:27

    I haven't seen a multiplication-based solution yet. Logarithm, divison, and string-based solutions will become rather unwieldy against millions of test cases, so here's one for ints:

    /**
     * Returns the number of digits needed to represents an {@code int} value in 
     * the given radix, disregarding any sign.
     */
    public static int len(int n, int radix) {
        radixCheck(radix); 
        // if you want to establish some limitation other than radix > 2
        n = Math.abs(n);
    
        int len = 1;
        long min = radix - 1;
    
        while (n > min) {
            n -= min;
            min *= radix;
            len++;
        }
    
        return len;
    }
    

    In base 10, this works because n is essentially being compared to 9, 99, 999... as min is 9, 90, 900... and n is being subtracted by 9, 90, 900...

    Unfortunately, this is not portable to long just by replacing every instance of int due to overflow. On the other hand, it just so happens it will work for bases 2 and 10 (but badly fails for most of the other bases). You'll need a lookup table for the overflow points (or a division test... ew)

    /**
     * For radices 2 &le r &le Character.MAX_VALUE (36)
     */
    private static long[] overflowpt = {-1, -1, 4611686018427387904L,
        8105110306037952534L, 3458764513820540928L, 5960464477539062500L,
        3948651115268014080L, 3351275184499704042L, 8070450532247928832L,
        1200757082375992968L, 9000000000000000000L, 5054470284992937710L,
        2033726847845400576L, 7984999310198158092L, 2022385242251558912L,
        6130514465332031250L, 1080863910568919040L, 2694045224950414864L,
        6371827248895377408L, 756953702320627062L, 1556480000000000000L,
        3089447554782389220L, 5939011215544737792L, 482121737504447062L,
        839967991029301248L, 1430511474609375000L, 2385723916542054400L,
        3902460517721977146L, 6269893157408735232L, 341614273439763212L,
        513726300000000000L, 762254306892144930L, 1116892707587883008L,
        1617347408439258144L, 2316231840055068672L, 3282671350683593750L,
        4606759634479349760L};
    
    public static int len(long n, int radix) {
        radixCheck(radix);
        n = abs(n);
    
        int len = 1;
        long min = radix - 1;
        while (n > min) {
            len++;
            if (min == overflowpt[radix]) break;
            n -= min;
            min *= radix;
    
        }
    
        return len;
    }
    

提交回复
热议问题