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