[英]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
具有預定義的常數0
, 1
,和10
( BigDecimal.ZERO
, BigDecimal.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.