首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何理解导致ArrayIndexOutOfBoundsException的模块计算的数学公式?

如何理解导致ArrayIndexOutOfBoundsException的模块计算的数学公式?
EN

Stack Overflow用户
提问于 2016-12-21 08:08:05
回答 1查看 141关注 0票数 2

添加这不是一个纯粹的ArrayIndexOutOfBoundsException问题,它是关于提醒计算算法,请不要标记为重复。

手机抛出ArrayIndexOutOfBoundsException,这是日志:

java.lang.IntegralToString.convertInt(IntegralToString.java:234) at java.lang.IntegralToString.appendInt(IntegralToString.java:173) at java.lang.StringBuilder.append(StringBuilder.java:139) at android.telephony.SignalStrength.toString(SignalStrength.java:1123) at com.android.internal.telephony.ServiceStateTracker.onSignalStrengthResult(ServiceStateTracker.java:958) at

异常发生在

buf-光标= DIGITSr;

我的问题是如何理解代码,例如

int q= (int) ((0x51EB851FL * i) >>> 37);

int q= (0xCCCD * i) >>> 19;

deleteWhy not int q=i/ 10;int r=i-10*q;

加法: int q= (0xCCCD * i) >>> 19;等效于int =i/ 10;

根据关于上述算法的注释,如果r是正确的,它们如何可以是120。

以下是有关守则:

代码语言:javascript
复制
private static final char[] TENS = {
    '0', '0', '0', '0', '0', '0', '0', '0', '0', '0',
    '1', '1', '1', '1', '1', '1', '1', '1', '1', '1',
    '2', '2', '2', '2', '2', '2', '2', '2', '2', '2',
    '3', '3', '3', '3', '3', '3', '3', '3', '3', '3',
    '4', '4', '4', '4', '4', '4', '4', '4', '4', '4',
    '5', '5', '5', '5', '5', '5', '5', '5', '5', '5',
    '6', '6', '6', '6', '6', '6', '6', '6', '6', '6',
    '7', '7', '7', '7', '7', '7', '7', '7', '7', '7',
    '8', '8', '8', '8', '8', '8', '8', '8', '8', '8',
    '9', '9', '9', '9', '9', '9', '9', '9', '9', '9'
};

/** Ones [i] contains the tens digit of the number i, 0 <= i <= 99. */
private static final char[] ONES = {
    '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
    '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
    '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
    '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
    '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
    '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
    '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
    '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
    '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
    '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
};
/**
 * The digits for every supported radix.
 */
private static final char[] DIGITS = {
    '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
    'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j',
    'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't',
    'u', 'v', 'w', 'x', 'y', 'z'
};

/**
     * Returns the string representation of i and leaves sb alone if sb is null.
     * Returns null and appends the string representation of i to sb if sb is non-null.
     */
    private static String convertInt(AbstractStringBuilder sb, int i) {
        boolean negative = false;
        String quickResult = null;
        if (i < 0) {
            negative = true;
            i = -i;
            if (i < 100) {
                if (i < 0) {
                    // If -n is still negative, n is Integer.MIN_VALUE
                    quickResult = "-2147483648";
                } else {
                    quickResult = SMALL_NEGATIVE_VALUES[i];
                    if (quickResult == null) {
                        SMALL_NEGATIVE_VALUES[i] = quickResult =
                                i < 10 ? stringOf('-', ONES[i]) : stringOf('-', TENS[i], ONES[i]);
                    }
                }
            }
        } else {
            if (i < 100) {
                quickResult = SMALL_NONNEGATIVE_VALUES[i];
                if (quickResult == null) {
                    SMALL_NONNEGATIVE_VALUES[i] = quickResult =
                            i < 10 ? stringOf(ONES[i]) : stringOf(TENS[i], ONES[i]);
                }
            }
        }
        if (quickResult != null) {
            if (sb != null) {
                sb.append0(quickResult);
                return null;
            }
            return quickResult;
        }

        int bufLen = 11; // Max number of chars in result
        char[] buf = (sb != null) ? BUFFER.get() : new char[bufLen];
        int cursor = bufLen;

        // Calculate digits two-at-a-time till remaining digits fit in 16 bits
        while (i >= (1 << 16)) {
            // Compute q = n/100 and r = n % 100 as per "Hacker's Delight" 10-8
            int q = (int) ((0x51EB851FL * i) >>> 37);
            int r = i - 100*q;
            buf[--cursor] = ONES[r];
            buf[--cursor] = TENS[r];
            i = q;
        }

        // Calculate remaining digits one-at-a-time for performance
        while (i != 0) {
            // Compute q = n/10 and r = n % 10 as per "Hacker's Delight" 10-8
            int q = (0xCCCD * i) >>> 19;
            int r = i - 10*q;
            buf[--cursor] = DIGITS[r];
            i = q;
        }

        if (negative) {
            buf[--cursor] = '-';
        }

        if (sb != null) {
            sb.append0(buf, cursor, bufLen - cursor);
            return null;
        } else {
            return new String(cursor, bufLen - cursor, buf);
        }
    }
EN

回答 1

Stack Overflow用户

发布于 2016-12-21 08:37:06

  1. int q = (int) ((0x51EB851FL * i) >>> 37);

数字开头的0x表示该数字是用十六进制表示形式写入的。

数字末尾的L表示数字是Long-typed。这就是为什么(int) cast使用。

>>>37意味着左边数字的二进制表示应该从这个表达式移到右边37次。例如:

代码语言:javascript
复制
16 >>> 2
16 in binary is 10000.
shift it to the right 2 times, we got 100.00
100 in decimal system is equal to 4.
16 >>> 2 = 4.
  1. 关于int q = (0xCCCD * i) >>> 19;也一样
  2. 为什么不int q = i / 10; int r = i - 10q;

国际海事组织对十六进制数的移动比除法要快得多,也更精确。

  1. 根据关于上述算法的注释,如果r是正确的,它们如何可以是120。

我确信您可以简单地在IDE中调试它以获得答案。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/41257938

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档