簡體   English   中英

如何使用BigDecimal遞增for循環?

[英]How do I increment a for loop using BigDecimal?

因此,在編碼方面,我或多或少是菜鳥。 我正在為大學課程學習Java,我的一項練習要求我編寫一個代碼,該代碼使用左端點方法,中點方法和梯形方法對整數進行求值。

為此,我需要使用一個for循環,該循環每次遞增一個步驟。 我知道僅使用double即可執行此操作,但是問題是,當我使用double數據類型運行計算時,會產生舍入錯誤。 閱讀完之后(主要是查看其他堆棧溢出問題),我認為我應該使用BigDecimal消除舍入錯誤。

但是,使用BigDecimal會給我帶來很多錯誤。 據我所知,我不能使用<,>,==等常規運算符,因為BigDecimal不是原始數據類型。 但是然后我不知道如何在仍然使用BigDecimal的同時進行遞增的基本for循環。 我在這里看到的另一件事建議使用Commons-math? (第二答案)

https://stackoverflow.com/questions/16707397/whats-wrong-with-this-simple-double-calculation# =

據我所知,我不知道如何使用它,這與例如普通的老式導入java.lang.Math不一樣。

所以我想我的問題是,如何才能在for循環中使用BigDecimal來使我的代碼正常工作,以及如何將數字進行一般比較,或者我如何才能使用Common-Math來完全避免舍入錯誤?

這是我的代碼:

import java.util.Scanner;
import java.lang.Math;
import java.math.BigDecimal;

public class IntegrationMethods{

  //calculates the value of the function f(x)=x^2
  public static BigDecimal f(BigDecimal x){
    return x.multiply(x);
  }

  //uses a, b and N as arguments, calculates sum of integral using left 
endpoint rule
  public static BigDecimal leftEndpoint(BigDecimal a, BigDecimal b, 
BigDecimal n){
    BigDecimal h = (b.subtract(a)).divide(n);
    sum = new BigDecimal("0");
    i = new BigDecimal("0");
    for(i.compareTo(n)<=0;){
      sum = sum.add(h.multiply(f(a.add(h.multiply(i-1)))));
      i = i.add(new BigDecimal(1));
    }
    return sum;
  }

  public static BigDecimal midpoint(BigDecimal a, BigDecimal b, BigDecimal 
n){
    BigDecimal h = (b.subtract(a)).divide(n);
    BigDecimal sum = 0.0;
    for(BigDecimal i=0.0; i<n; i++){
      BigDecimal x1 = a.add(h.multiply(i));
      BigDecimal x2 = a.add(h.multiply(i+1));
      sum = sum.add(h.multiply((f(x1).add(f(x2))).divide(2)));
    }
    return sum;
  }

  public static void main(String[] args){
    Scanner scanner = new Scanner(System.in);

System.out.println("Please enter the lower limit of integration a.");
BigDecimal a = scanner.nextBigDecimal();

System.out.println("Please enter the upper limit of integration b.");
BigDecimal b = scanner.nextBigDecimal();

//swaps a and b so that the bigger of the two is always b.
//this prevents a negative popping up later on.
if(b<a){
  BigDecimal r = a;
  BigDecimal m = b;
  a = m;
  b = r;
}

System.out.println("Please enter the number of sampling points N.");
BigDecimal n = scanner.nextBigDecimal();

//checks if n is greater than or equal to 1, and asks for a new value if it isn't.
while (n<1.0){
  System.out.println("Please enter a new value for N.");
  n = scanner.nextBigDecimal();
}

System.out.println("For " + n + " intervals, the integral of x^2 using the left endpoint rule is: " + leftEndpoint(a,b,n));
System.out.println("Using the midpoint rule, the integral of x^2 is: " + midpoint(a,b,n));
  }
}

從0到19計數的普通循環為:

for (int i = 0; i < 20; i++)
    System.out.println(i);

使用BigDecimal完成的相同循環如下所示:

BigDecimal end = BigDecimal.valueOf(20);
for (BigDecimal i = BigDecimal.ZERO; i.compareTo(end) < 0; i = i.add(BigDecimal.ONE))
    System.out.println(i);

BigDecimal使用<>==等的方法是使用compareTo()方法。 Javadoc顯示了如何執行此操作:

對於六個布爾比較運算符(<,==,>,> =,!=,<=)中的每一個,該方法優先於單個方法提供。 建議執行這些比較的慣用法是: (x.compareTo(y) <op> 0) ,其中<op>是六個比較運算符之一。

因此, i < end被寫為i.compareTo(end) < 0

還要注意, BigDecimal具有預定義的常數01 ,和10BigDecimal.ZEROBigDecimal.ONE ,和BigDecimal.TEN ),並且創建BigDecimal整數值應該使用BigDecimal.valueOf(long val)而不是new BigDecimal(String val)

每個for循環都可以具有您想要的任何表達式。 第一個初始化變量,第二個必須求值布爾值,第三個是任何表達式。 因此,例如:

for (BigDecimal i = BigDecimal.ZERO; i.compareTo(n) < 0; i = i.add(BigDecimal.ONE)) {
}

使用BigDecimal類的浮點值作為循環計數器是一個壞主意,因為它可能導致意外行為。 您可以在此處閱讀有關此內容的更多信息: https : //www.securecoding.cert.org/confluence/display/java/NUM09-J.+Do+not+use+floating-point+variables+as+loop+counters

如果您將in-for計數器設為int類型,則可以將其包裝在新的BigDecimal實例中,以傳遞給h.multiply()並產生預期的結果:

for(int i=0; BigDecimal.of(i).compareTo(n) < 0; i++){
  BigDecimal x1 = a.add(h.multiply(BigDecimal.of(i)));
  BigDecimal x2 = a.add(h.multiply(BigDecimal.of(i+1)));
  sum = sum.add(h.multiply((f(x1).add(f(x2))).divide(2)));
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM