Java 需要有关教育娱乐游戏程序的帮助

Java 需要有关教育娱乐游戏程序的帮助,java,math,Java,Math,我正在研究一个因式分解问题,对于较小的数字,它工作得很好。我已经能够计算小数字的因子(从Wolfram Alpha获得答案),就像维基百科页面上的因子(5959) 随着维基百科页面的出现,我一直在阅读。再一次,由于我的数学知识很差,我无法理解下一步需要做什么 编辑:它终于起作用了!一旦我的工作代码完全正常,我会将其发布到这里,以便其他处于我困境中的人可以从中学习。那getIntSqrt()方法。。。我不知道它是否正常,但它看起来很糟糕(将BigInteger转换为字符串??)你检查过了吗 是一种

我正在研究一个因式分解问题,对于较小的数字,它工作得很好。我已经能够计算小数字的因子(从Wolfram Alpha获得答案),就像维基百科页面上的因子(5959)

随着维基百科页面的出现,我一直在阅读。再一次,由于我的数学知识很差,我无法理解下一步需要做什么

编辑:它终于起作用了!一旦我的工作代码完全正常,我会将其发布到这里,以便其他处于我困境中的人可以从中学习。

getIntSqrt()
方法。。。我不知道它是否正常,但它看起来很糟糕(将BigInteger转换为字符串??)你检查过了吗

是一种(显然)更好的方法。

您的
isSqrt()
函数对于您尝试执行的操作不正确。你想 确切地知道是否
n=root^2
,但是如果
n
仅存在于区间
(根^2,(根+1)^2)

我认为您需要做的就是检查循环中的
n
是否等于
root.pow(2)

// while b2 not square
while(!(isSqrt(b2, root))) {
以下说明的目的是什么

    root = root.add(b2.divide(root)).divide(TWO);
我认为,为了检查
b2
是否为平方,您应该尝试使用您已有的方法计算平方根(上述指令只是计算平方根的标准算法的一个步骤):

    root = getIntSqrt(b2);
同样的观察也适用于本规范:

// ??
final int bitLength = N.bitLength();
BigInteger root = BigInteger.ONE.shiftLeft(bitLength / 2);
root = root.add(b2.divide(root)).divide(TWO);
编辑。问题是,您的
sqrt()
方法需要一个
isSqrt()
来检查
root
是否是
n
的近似根,而
fermat()
中的循环需要一个精确的检查。 我附加了一些似乎通过了上次测试的代码:

import java.math.BigInteger;

public class Fermat {

private BigInteger a, b, N;
private static final BigInteger TWO = BigInteger.valueOf(2);

private static boolean isApproximateSqrt(BigInteger n, BigInteger root) {
    final BigInteger lowerBound = root.pow(2);
    final BigInteger upperBound = root.add(BigInteger.ONE).pow(2);
    return lowerBound.compareTo(n) <= 0
        && n.compareTo(upperBound) < 0;
}

private static BigInteger intSqrt(BigInteger n) {
    if (n.signum() >= 0) {
        final int bitLength = n.bitLength();
        BigInteger root = BigInteger.ONE.shiftLeft(bitLength / 2);

        while ( ! isApproximateSqrt(n, root) ) {
            root = root.add(n.divide(root)).divide(TWO);
        }
        return root;
    } else {
        throw new ArithmeticException("square root of negative number");
    }
}

private void init() {
    a = intSqrt(N);                             // a <- ceil(sqrt(N))
    BigInteger b2, root;
    do {
        a = a.add(BigInteger.ONE);              // a <- a + 1
        b2 = (a.multiply(a)).subtract(N);       // b2 <- (a * a) - N
        root = intSqrt(b2);
    } while( root.pow(2).compareTo(b2) != 0 );  // while b2 not exact sqrt
    b = root;
}

public void print() {
    BigInteger a2 = a.pow(2);
    BigInteger b2 = b.pow(2);
    BigInteger squareDifference = a2.subtract(b2);
    System.out.println("A: " + a + "\nB: " + b);
    System.out.println("A^2: " + a2 + "\nB^2: " + b2);
    System.out.println("N: " + N);
    if(squareDifference.compareTo(N) != 0) {
        System.out.println("Something is wrong....");
    }
}

public Fermat(BigInteger aNumber) {
    N = aNumber;
    init();
}

public static void main(String[] args) {
    Fermat f = new Fermat(new BigInteger("90283"));
    f.print();
}
}
import java.math.biginger;
公共级费马{
私有大整数a,b,N;
私有静态final biginger 2=biginger.valueOf(2);
私有静态布尔isApproximateSqrt(BigInteger n,BigInteger根){
final biginger lowerBound=root.pow(2);
final biginger上限=root.add(biginger.ONE).pow(2);
返回lowerBound.compareTo(n)=0){
最终整数位长度=n.位长度();
biginger root=biginger.ONE.shiftLeft(位长/2);
而(!isApproximateSqrt(n,root)){
root=root.add(n.divide(root)).divide(二);
}
返回根;
}否则{
抛出新的算术异常(“负数的平方根”);
}
}
私有void init(){

a=intSqrt(N);//a它是怎么不工作的?它在做什么“错误的”?错误的结果、异常等?你确定它适用于
5959=101*59
?抱歉,我漏掉了那一位。它在处理较长的数字时返回了错误的值。我遵循维基百科算法,当a、b、a2和b2的值在较长的数字中显示相同的结果时,它会显示不同的结果Wolfram Alpha.trashgod:好吧,程序声明6400-5959=441,当5959运行时显示的结果。根据维基百科a^2-N=b^2,该程序适用于该N.@Ender:我的错误,
5959=101*59=(80+21)*(80-21)
。它工作得很好,但我还是取出了它,并用建议的方法替换了它。尽管如此,程序仍然显示错误的结果。我不确定我是否正确地理解了你。你的意思是我应该放弃我的isSqrt()方法,只检查n是否等于root.pow(2)?我添加了更改,但代码从未进入while循环。我在代码中更改了它,但现在while循环让方块消失。程序现在输出A^2=158404和B^2=68121。最后158404-68121=90283。它工作了!我尝试过的每个测试用例似乎都工作了,所以我现在接受这个答案,除非我发现任何问题。比非常感谢您的帮助!它看起来棒极了,感谢您澄清了这一点。代码在我正在开发的应用程序(一个教育娱乐游戏)中运行良好。