gpt4 book ai didi

java - RoundingMode.DOWN 用于 BigDecimal 向上取整

转载 作者:行者123 更新时间:2023-12-04 10:59:44 41 4
gpt4 key购买 nike

我正在尝试编写一个程序,该程序使用牛顿法计算用户提供的指定精度 (k) 的整数 (n) 的平方根。该程序运行良好,但我注意到我认为是一个舍入问题。有人可以帮我解决这个问题吗?

例如:

  • 对于输入:n = 81 和 k = 7/对于输入:n = 87026 和 k = 11
  • 程序正在打印:9.0000001/程序正在打印:295.00169491039
  • 我要打印的内容:9.0000000/我要打印的内容:295.00169491038

  • 这是我的代码:
    Scanner userInput = new Scanner(System.in);
    //print instructions and scan user input
    System.out.println("~ This program computes the square root of an integer ~");
    System.out.print("\n" + "Enter a non-negative integer [not greater than 1 billion (10^9)] n: ");
    int n = userInput.nextInt();
    System.out.print("\n" + "Enter a non-negative integer [not greater than 10 thousand (10^4)] k: ");
    int k = userInput.nextInt();
    userInput.close();
    // declaring and converting variables
    int p = (k + 1);
    BigDecimal num = new BigDecimal(n);
    BigDecimal guess = new BigDecimal(n);
    BigDecimal newGuess;
    BigDecimal sqrt;
    // calculating error using int p
    BigDecimal error = BigDecimal.ONE.movePointRight(-p);
    // calculating guess using int p
    BigDecimal diff = BigDecimal.ONE.scaleByPowerOfTen(p);
    // newton's loop
    while (diff.compareTo(error) == 1) {
    newGuess = guess.subtract(
    ((guess.multiply(guess)).subtract(num))
    .divide(guess.add(guess), k, RoundingMode.DOWN));
    diff = newGuess.subtract(guess);
    if (diff.signum() == -1) {
    diff = diff.abs();
    }
    guess = newGuess;
    }
    // printing sqrt to screen
    sqrt = guess;
    System.out.println("loop calculated: " + "\n" + sqrt);

    最佳答案

    在循环中,根据牛顿法迭代计算总和,由此每个被加数被四舍五入并导致误差。为了说明这一点,额外输出 guess 的初始值很有用。以及 diff 的所有值.例如 n = 81, k = 7输出是:

    guess: 81
    diff: 40.0000000
    diff: 19.5121951
    diff: 8.8591124
    diff: 3.1073634
    diff: 0.5070567
    diff: 0.0142611
    diff: 0.0000112
    diff: 0E-7
    loop calculated:
    9.0000001

    如果所有 diff - 值从 guess 中减去,准确值为 9.0000001 ,即个别舍入误差导致偏差 0.0000001 .要改变这种行为,可以增加比例,例如通过一, k += 1 , 在循环之前,并使用 guess = guess.setScale(k - 1, RoundingMode.DOWN); 重置为实际值循环后。然后输出是:
    guess: 81
    diff: 40.00000000
    diff: 19.51219512
    diff: 8.85911242
    diff: 3.10736339
    diff: 0.50705669
    diff: 0.01426108
    diff: 0.00001129
    diff: 0E-8
    loop calculated:
    9.0000000

    现在结果符合预期。可以使用第二个示例 n = 87026 , k = 11 验证更改。 ,其输出没有变化:
    guess: 87026
    diff: 43512.50000000000
    diff: 21755.75001149068
    diff: 10876.87510915519
    diff: 5436.43840462864
    diff: 2714.22604199009
    diff: 1349.16761702433
    diff: 659.01405739182
    diff: 300.74946658011
    diff: 107.35187252479
    diff: 18.35523727653
    diff: 0.56993647588
    diff: 0.00055055104
    diff: 5.1E-10
    diff: 0E-11
    loop calculated:
    295.00169491039

    结果中出现模拟错误。修改后的输出是:
    guess: 87026
    diff: 43512.500000000000
    diff: 21755.750011490686
    diff: 10876.875109155187
    diff: 5436.438404628644
    diff: 2714.226041990089
    diff: 1349.167617024336
    diff: 659.014057391816
    diff: 300.749466580112
    diff: 107.351872524786
    diff: 18.355237276533
    diff: 0.569936475871
    diff: 0.000550551041
    diff: 5.13E-10
    diff: 0E-12
    loop calculated:
    295.00169491038

    按照预期值。

    关于java - RoundingMode.DOWN 用于 BigDecimal 向上取整,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58899222/

    41 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com