我试图用线程计算java中的neper数e。
我正在使用收敛行和((3-4 * k ^ 2)/(2 * k + 1)!)。
用户可以确定程序将使用多少个线程以及将完成多少次迭代。
每个线程的间隔为1 / numberOfThreads的一部分。我必须尽快做到这一点。
但是我遇到了阶乘函数的问题;在输出文件中,我得到0E-20 ...如果有人可以帮我解决这个问题,我将非常感激。
public class CalculateE {
static BigDecimal result = BigDecimal.ZERO;
static BigDecimal f = BigDecimal.ONE;
static BigDecimal f1 = BigDecimal.ONE;
static BigDecimal f_rev = BigDecimal.ONE;
static BigDecimal fact = BigDecimal.ONE;
static BigDecimal fact_rev = BigDecimal.ONE;
public static BigDecimal factorial(int x){
BigDecimal prod = BigDecimal.ONE;
for (int i=x; i>1; i--){
prod = prod.multiply(new BigDecimal(i));
}
return prod;
}
public static Runnable getRunner(final int from, final int to, int iter){
Runnable runner = new Runnable(){
@Override
public void run(){
BigDecimal e = BigDecimal.ZERO;
for (int i=from; i<to && i<=iter/2; i++){
if(i == from){
fact = factorial(2*i+1);
}else{
fact=fact.multiply(BigDecimal
.valueOf((2*i)*(2*i+1)));
}
e = e.add(BigDecimal
.valueOf(3 - 4*Math.pow(i, 2))
.divide(fact,
new MathContext(10000,RoundingMode.HALF_EVEN)));
}
addResult(e);
}
};
return runner;
}
//public static synchronized void addResult(BigDecimal e){
// result = result.add(e);
//}
public static synchronized void addResult(BigDecimal e){
result = result.add(e);
}
public static void main(String args[]){
//Default values
// Number of Threads used
int NumOfth = 1;
// Number of Iterations
int p = 1000;
//Quiet mode
Boolean quiet = false;
//Output file
String nameOffile = "result.txt";
// A check for command line arguments
for (int i = 0; i < args.length; i++) {
if (args[i].equals("-p")) {
p = new Integer(args[i + 1]);
}
if (args[i].equals("-t")){
NumOfth = new Integer(args[i+1]);
}
if (args[i].equals("-q")){
quiet = true;
System.out.println("Quiet mode enabled.");
}
if (args[i].equals("-o")){
nameOffile = args[i+1];
}
}
//Check for correct input
if (p <= 0 || NumOfth <= 0 || args.length > 7) {
System.out.println("ERROR: Args are not correct!!!");
} else{
long start1 = System.currentTimeMillis();
if (quiet == false){
System.out.println("Threads used in current run: " + NumOfth);
}
Runnable r[] = new Runnable[NumOfth];
Thread[] myThreads;
myThreads = new Thread[NumOfth];
int from = 0;
int to = (p/(NumOfth*2));
int interval = to - from;
for (int i = 0; i<NumOfth; i++){
//Create a runnable object
r[i] = getRunner(from, to, p);
// Create our threads over our runnable object
Thread thrd = new Thread(r[i]);
if (quiet == false){
System.out.println("Thread <" + i + "> created.");
}
thrd.start();
if (quiet == false){
System.out.println("Thread <" + i + "> started.");
}
myThreads[i] = thrd;
from = to + 1;
to = to + interval+1;
}
for (int i = 0; i<NumOfth; i++){
try{
//System.out.println("Thread <" + i + "> started.");
myThreads[i].join();
} catch (InterruptedException e){
e.printStackTrace();
}
}
if(quiet == false){
System.out.println("e = " + result.setScale(20, BigDecimal.ROUND_HALF_UP));
}
//Write the result to a file
//File myfile = new File(nameOffile);
Writer writer = null;
try{
writer = new BufferedWriter(new OutputStreamWriter(
new FileOutputStream(nameOffile), "utf-8"));
writer.write("" + result.setScale(20, BigDecimal.ROUND_HALF_UP));
} catch(IOException e) {
e.printStackTrace();
} finally {
try {
// close the file
writer.close();
} catch(Exception ex) {
//ignore
}
}
//Current time
long stop = System.currentTimeMillis();
//Time for execution
long diff = stop - start1;
System.out.println(diff + " ms");
System.out.println(count);
}
}
}