我正在研究 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

  • 7
    如何定义非整数的可整除性?


    – 

  • 1
    @Sören 的观点很好。非整数的可整除性是什么意思?现在我仔细想想,我意识到我误读了这个问题。我认为书中所说的“有 50 位小数的数字”是指“有 50 位数字的整数”,而不是“小数点后有 50 位数字的数字”。


    – 

  • 1
    @Osmium 即使你的算法能在宇宙热寂中完成(它不会 – 它是 1.4×10^51 次操作),它也永远不会给出非整数的结果。它打印 0、2、3、4、6、8、9、10、12、14。它只是运行得非常慢。小数除以整数的余数永远不会是 0(此部分remainder.compareTo(BigDecimal.ZERO):)


    – 


  • 我应该先花点时间理解问题,而不是不好好思考问题就直接开始编码。吸取教训。


    – 

  • 3
    我建议你想使用BigInteger,而不是BigDecimal


    – 


最佳答案
2

您没有无限循环。您的增量太小,除法需要很多很多次迭代才能最终找到一个可以被 2 或 3 整除的数字。如果我将增量​​更改为 0.01,我几乎可以立即得到结果。使用 0.00001 需要几秒钟才能找到结果。我不知道使用您的增量找到第一个结果 (2) 需要多长时间,但不是几秒钟,甚至不是几小时,甚至可能不是几周 – 很可能超过一年。(打印消息也无济于事。)

2

  • 2
    它需要 2e50 次循环才能numbers变成2.0第一个退出循环的数字。假设在 .00001(1e5)处找到结果需要 1 秒,并且鉴于这是一种算法,我们可以线性扩展该时间:在打印此代码之前需要=O(n) 63350 2e50/1e5


    – 


  • 哇哦,我差太远了 😉


    – 

我明白这个问题应该通过编写程序来解决问题,因为这就是你想要练习的……

但是,当仅寻找 2 和 3 作为除数时,测试除法余数是否为 0 的方法是有问题的。

众所周知,每个偶数都可以被 2 整除,因此只需测试数字的最后一位数字是否为偶数。

如果某个数的各位数字之和能被三整除(或者说是 3、6 或 9),则该数能被 3 整除。好的,我们可以讨论一下除以 3 并检查余数是否比获取数字的各位数字并(反复)求和,然后检查它是 3、6 还是 9 更快。

只有当除数为 7 时才需要使用“强力”方法(只要我们保持在 2 和 9 之间)。

1

  • 这些是需要考虑的要点。谢谢。


    –