【问题标题】:How does the getChar function work?getChar 函数是如何工作的?
【发布时间】:2017-12-08 16:39:45
【问题描述】:
private static char[] getChars(int i) {
    char buf[] = new char[32];
    int q;
    for (int j = 31; j >= 0; j--) {
         q = (i * 52429) >>> (19);
         int r = i - ((q << 3) + (q << 1));
         buf[j] = (char) (r + '0');
         i = q;
         if (i == 0)
             break;
    }

 return buf;
}

上面的代码是基于java.lang.Integer.getChars(int)的一部分。开发人员是如何想出这个“神奇”数字 52429 的。它背后的数学原理是什么?输入 81920 后,此功能不起作用。这个幻数是否只适用于特定范围的输入,如果是,为什么?

【问题讨论】:

  • 这个方法属于什么类?
  • @Seelenvirtuose 哎呀,OP 更新了。它在 java.lang.Integer
  • 我只在java.lang.Integer(JDK7和JDK8)中看到了一个方法static void getChars(int i, int index, char[] buf)。困惑...
  • @Seelenvirtuose 在 JDK8 中,在第 456 行:hg.openjdk.java.net/jdk8/jdk8/jdk/file/687fd7c7986d/src/share/…(注意这是一个private 方法)
  • @Seelenvirtuose 问题说显示的代码是“基于 部分 java.lang.Integer.getChars(int)”。问题是询问魔术数字52429。我只是指出,在 JDK8 中,该幻数位于第 456 行。作为my answer says,幻数来自一本书。

标签: java algorithm binary


【解决方案1】:

如果您搜索源代码,您会找到该数字的第二个实例:

// I use the "invariant division by multiplication" trick to
// accelerate Integer.toString.  In particular we want to
// avoid division by 10.
//
// The "trick" has roughly the same performance characteristics
// as the "classic" Integer.toString code on a non-JIT VM.
// The trick avoids .rem and .div calls but has a longer code
// path and is thus dominated by dispatch overhead.  In the
// JIT case the dispatch overhead doesn't exist and the
// "trick" is considerably faster than the classic code.
//
// TODO-FIXME: convert (x * 52429) into the equiv shift-add
// sequence.
//
// RE:  Division by Invariant Integers using Multiplication
//      T Gralund, P Montgomery
//      ACM PLDI 1994
//

所以,您的问题的答案可以在 T Gralund, P Montgomery 的书 Division by Invariant Integers using Multiplication 中找到。

【讨论】:

  • 为什么最大值限制在 81920?
  • @QuestionEverything 至于为什么,看书吧。但是请注意,在 JDK8 中,它仅限于 65536。请参阅第 453 行的评论:hg.openjdk.java.net/jdk8/jdk8/jdk/file/687fd7c7986d/src/share/…
  • @QuestionEverything: 因为 81919 * 52429 只适合 32 位,但 81920 * 52429 不再适合。
猜你喜欢
  • 2015-04-15
  • 2021-12-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-05-25
  • 1970-01-01
  • 2021-03-30
相关资源
最近更新 更多