2009-07-17 116 views
1

相当容易,如果BigInteger的数量是543,我希望它切断了最后一位,使其54Java的BigInteger,以切断最后一位

两种简单的方法来做到这一点可能是:

  1. 使用字符串,获取子字符串并使用新值创建新的biginteger。
  2. 使用BigIntegers划分方法与标记10(10分之543= 54.3 => 54)

的事情是我将与课程的大整数来执行此的次数很多

我的猜测是,玩弄字符串会慢一些,但是我再也没有使用Bigintegers,也不知道“除法”操作有多昂贵。

速度在这里是必不可少的,实现这个速度的最快方法是什么(内存速度没有问题)?

其他解决方案也是受欢迎的。

+0

您真正知道的唯一方法 - 并且真正知道问题的重要性 - 是分析您的应用程序。我怀疑toString()会比较慢,但实际上并没有尝试过。 – kdgregory 2009-07-17 17:50:22

+5

如果你威胁要削减大整数的最后一位数字,我认为执行速度将是你最担心的问题。我听说他们很狡猾,反击! – Totty 2009-07-17 17:55:48

+0

@Totty哈哈,让我笑了:D – Milan 2009-07-17 17:58:03

回答

3

除以10比使用子串操作快得多。使用以下基准,我得到大约161倍(比例与位数成正比)

long divTime = 0; 
    long substrTime = 0; 
    final int bitsCount = 1000; 

    for (int i = 0; i < 1000; ++i) { 
     long t1, t2; 
     BigInteger random = new BigInteger(bitsCount, new Random()); 

     t1 = System.currentTimeMillis(); 
     random.divide(BigInteger.TEN); 
     t2 = System.currentTimeMillis(); 
     divTime += (t2 - t1); 

     t1 = System.currentTimeMillis(); 
     String str = random.toString(); 
     new BigInteger(str.substring(0, str.length() - 1)); 
     t2 = System.currentTimeMillis(); 
     substrTime += (t2 - t1); 
    } 

    System.out.println("Divide: " + divTime); 
    System.out.println("Substr: " + substrTime); 
    System.out.println("Ratio: " + (substrTime/divTime)); 
5

除以10最有可能会更快。

0

最快的方法是用有效的内部分割实现将数字除以10。该操作的内部是在幕后,但肯定是不平凡的,因为该数字存储在base-2中。

-7

如果性能是至关重要的...不要用java

在其编译成机器代码语言(如C或C++)的整数除法是一个巨大的因素更快。字符串操作使用(或可以使用)内存分配,因此速度很慢。

我敢打赌,在Java int分区也会更快。否则他们的虚拟机执行是非常奇怪的。

2

如果您创建一个数字为10的静态BigInteger,然后用它除以10,那么这可能是最快的方法。它每次都会创造一个临时的新BigInteger。

子字符串的问题在于你实际上每创建一个新字符串都会更慢,更不用说慢速迭代通过字符串来获取其子字符串。

1

最快的实现方式可能是使用内部表示使用基数10的数据类型,即某种BCD。然后,除以10将意味着丢弃最后一个字节(或者,如果以正确的方式实现,则甚至只是递增/递减索引)。

当然,你必须从头开始实施所有的算术和其他操作,这使得这项工作很多。

0

即使提出这个问题也许为时过早。以明显的方式去做(除以十),然后进行基准测试,并在需要时对其进行优化。转换为字符串表示并返回将会慢得多。

0

单独的toString()可能比子字符串慢。

0

不同的人都说,除以10会比转换为字符串并取得子字符串更快。要理解为什么,只需考虑从BigInteger转换为String的计算,反之亦然。例如:

/* simplified pseudo code for converting +ve numbers to strings */ 
StringBuffer sb = new StringBuffer(...); 
while (number != 0) { 
    digit = number % 10; 
    sb.append((char)(digit + '0')); 
    number = number/10; 
} 
return sb.toString(); 

需要注意的重要一点是,从多个转换成字符串需要通过反复10.除以实际上分割数正比于日志10(数量)。沿着另一个方向进行log10(数字)乘法运算。很显然,这比单个分区的计算量多10个。