我正在研究 Java 教科书上的一道题,要求找出前 10 个有 50 位小数并且能被 2 或 3 整除的数字。这是我的代码:
import java.math.*;
public class Divisible {
public static void main(String[] args) {
BigDecimal numbers = new BigDecimal("0.00000000000000000000000000000000000000000000000000");
BigDecimal number2 = new BigDecimal("2.0");
BigDecimal number3 = new BigDecimal("3.0");
BigDecimal increment = new BigDecimal("0.00000000000000000000000000000000000000000000000001");
int count = 0;
while (count < 10) {
boolean isDivisibleBy2 = isDivisible(numbers, number2);
boolean isDivisibleBy3 = isDivisible(numbers, number3);
if (isDivisibleBy2 || isDivisibleBy3) {
System.out.println(numbers);
count++;
} else {
System.out.println("No divisor.");
}
numbers = numbers.add(increment);
}
}
private static boolean isDivisible(BigDecimal number, BigDecimal divisor) {
BigDecimal remainder = number.remainder(divisor);
return remainder.compareTo(BigDecimal.ZERO) == 0;
}
}
但是此代码陷入了打印“无除数”的无限循环。
我认为问题出在isDivisible
方法上,该remainder
方法检查可分性。
我将非常感激您对我当前方法提出的任何建议。
8
最佳答案
2
您没有无限循环。您的增量太小,除法需要很多很多次迭代才能最终找到一个可以被 2 或 3 整除的数字。如果我将增量更改为 0.01,我几乎可以立即得到结果。使用 0.00001 需要几秒钟才能找到结果。我不知道使用您的增量找到第一个结果 (2) 需要多长时间,但不是几秒钟,甚至不是几小时,甚至可能不是几周 – 很可能超过一年。(打印消息也无济于事。)
2
-
2它需要 2e50 次循环才能
numbers
变成2.0
第一个退出循环的数字。假设在 .00001(1e5)处找到结果需要 1 秒,并且鉴于这是一种算法,我们可以线性扩展该时间:在打印此代码之前,需要=O(n)
633502e50/1e5
…
–
-
哇哦,我差太远了 😉
–
|
我明白这个问题应该通过编写程序来解决问题,因为这就是你想要练习的……
但是,当仅寻找 2 和 3 作为除数时,测试除法余数是否为 0 的方法是有问题的。
众所周知,每个偶数都可以被 2 整除,因此只需测试数字的最后一位数字是否为偶数。
如果某个数的各位数字之和能被三整除(或者说是 3、6 或 9),则该数能被 3 整除。好的,我们可以讨论一下除以 3 并检查余数是否比获取数字的各位数字并(反复)求和,然后检查它是 3、6 还是 9 更快。
只有当除数为 7 时才需要使用“强力”方法(只要我们保持在 2 和 9 之间)。
1
-
这些是需要考虑的要点。谢谢。
–
|
–
–
remainder.compareTo(BigDecimal.ZERO)
:)–
–
BigInteger
,而不是BigDecimal
。–
|