【问题标题】:Relational Operation on two BigIntegers in JavaJava中两个BigInteger的关系运算
【发布时间】:2014-06-15 20:35:30
【问题描述】:

在尝试使用 BINARY SEARCH 方法计算 BigInteger平方根 时,我被困在如何计算 BigInteger 之间strong>两个 BigIntegers 用于满足比较操作。 比如,我想检查两个 BigInteger 变量之间的相等性大于或小于条件。

这是错误的代码,大​​致了解我想要执行的操作。任何解决问题的努力将不胜感激。

public static BigInteger squareroot(BigInteger bi){
    //BigInteger bkl;
    BigInteger low,high,mid;
low=ONE;
high=bi.add(ZERO);
while(low<=high)
{
    mid =(low.add(high)).divide(new BigInteger("2"));
    if(mid.multiply(mid).equals(bi))
        return mid;
    if(mid.multiply(mid) > bi)
        high = mid -1 ;
    else
        low = mid + 1;
}
return mid;
}

【问题讨论】:

  • 平方根的二进制搜索?它是如何工作的?
  • @ElliottFrisch 它执行二进制搜索,高为平方,低为 0,当二进制搜索找到作为平方根的整数时返回。
  • @Human 我在 OP 的帖子中没有看到数组(连续或其他)。另外,如果我传入10
  • @ElliottFrisch 我说错了,它以高数为平方 + 1 和低数为 0 开始。它收敛于平方根,就像在数组。
  • 当您运行这段代码时,您可以粗略估计将 10 的平方根近似为 3。

标签: java biginteger binary-search comparison-operators


【解决方案1】:

BigIntegers 是Objects,所以你不能将它们的内容与&gt; 等关系运算符进行比较,而== 不会比较内容;它会比较对象引用。

但是,BigInteger 确实实现了Comparable&lt;BigInteger&gt;,因此请改为调用compareTo

  • 对于相等,使用left.compareTo(right) == 0
  • 小于,请使用left.compareTo(right) &lt; 0
  • 对于大于,使用left.compareTo(right) &gt; 0

【讨论】:

  • 但这不是我的问题。执行此操作后我会收到什么???我想比较两个 BigInteger 的大于或小于关系。我将如何使用这个 Comparable 接口来帮助我实现这一目标?
  • 致电compareTo 肯定会对您有所帮助。您将能够通过调用compareTo 来比较两个BigIntegers 的值。您可以通过调用 compareTo(由 Comparable 定义)来“使用”Comparable。必须定义 compareTo 方法,因为 BigInteger 声明它实现了 Comparable。
  • 虽然总是欢迎您回答自己的问题,但我看不出重复会有什么好处。
【解决方案2】:

您没有正确使用BigInteger 类:

  1. 您可以将high = bi.add(ZERO) 替换为简单的high = bi
  2. 比较 low &lt;= high 不会为 BigInteger 操作数编译。
  3. 比较 mid.multiply(mid) &gt; bi 不会为 BigInteger 操作数编译。
  4. 算术运算mid-1mid+1 不会针对BigInteger 操作数进行编译。
  5. 使用divide(new BigInteger("2"))效率不是很高;请改用shiftRight(1)

试试这个方法:

public static BigInteger squareroot(BigInteger bi)
{
    BigInteger low  = BigInteger.ZERO;
    BigInteger high = bi;
    while (true)
    {
        BigInteger mid0 = low.add(high).shiftRight(1);
        BigInteger mid1 = mid0.add(BigInteger.ONE);
        BigInteger square0 = mid0.multiply(mid0);
        BigInteger square1 = mid1.multiply(mid1);
        if (square0.compareTo(bi) > 0)
            high = mid0;
        else if (square1.compareTo(bi) <= 0)
            low = mid1;
        else
            return mid0;
    }
}

【讨论】:

  • @shekhar:嗯,你已经更改了问题中的代码,所以我会在几分钟内删除这个答案......
  • 如果我分配high=bi,我的目的就不会解决。请改正!
  • @shekhar:你错了。您代码中的high=bi.add(ZERO) 相当于我的代码中的high=bi。除此之外,您的代码中还有几个错误:1. while(low&lt;=high)。 2.if(mid.multiply(mid) &gt; bi)。最后,您对divide(new BigInteger("2") 的使用效率不是很高,您可以通过将其替换为shiftRight(1) 来改进它。
  • 所以,您可能应该已经匆忙阅读了这个问题。我已经提到我正在展示我的错误代码,只是为了对我想要实现的目标给出一个公平的想法。而且,你接管high=bi是错误的,因为在这个程序中,不需要引用bi的地址,而是一开始只是为了提供一个实例化!
  • @shekhar:我认为您对 Java 的看法是错误的!当您实例化high=bi 时,并不意味着bi 会随着high 的变化而变化。使用high=bi.add(ZERO) 创建一个新实例与high=bi 没有不同的效果(除了重复的实例,所以如果有的话,它会使你的代码性能变差)!
猜你喜欢
  • 1970-01-01
  • 2012-11-30
  • 1970-01-01
  • 1970-01-01
  • 2021-08-05
  • 1970-01-01
  • 2011-05-13
  • 2019-09-08
  • 2016-08-02
相关资源
最近更新 更多