Getting printed text to align properly - java

I'm a totally novice programmer, and I'm pretty confused by how to use printf. The use of printf in my code is at the end of the paymentCalc method; I'm trying to print data to a line, specify 2 decimal points to print, and pad it 10 spaces before printing the next output.
The code isnt formatting at all. What am I doing wrong here? It's all printing on the same line, but it's printing a million decimals, and it doesnt seem to be padding properly.
/*
* Step 1: Get starting annual interest rate
* Step 2: Get ending annual interest rate
* Step 3: Get increment rate
* Step 4: Get First # of years for repayment
* Step 5: Get Last # of years for repayment
* Step 6: Get # of years to increment by
* Step 7: Get loan amount
*
* Convert annual rates to monthly rates MIR = Annual rate/12
* MTP = # of years * 12
*
* MIR = monthly interest rate
* MTP = months to pay
* Annuity Factor =(mir*(1+mir)^mtp)/(((1+mir)^mtp)-1)
* Payment = Amount Loaned * Annuity Factor
*
*
* Produce a list of possible loan payments
* Based on a series of annual interest rates
* Start at user entered rate and increment until it hits user entered max
* Display annual payment as monthly payments
* */
import java.io.*;
import java.util.*;
import java.text.*;
import java.math.*;
public class methodshomework {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
//VARIABLES
//amounts in years
double startAnnInt = 0;
double endAnnInt = 0;
double incRate = 0;
double incRatePercent = 0;
double firstYears = 0;
double lastYears = 0;
double incYears = 0;
double loanAmt = 0;
//amounts in months
double startMonthInt = 0;
double endMonthInt = 0;
double monthIncRate = 0;
double firstMonths = 0;
double lastMonths = 0;
double incMonths = 0;
double monthIncRatePercent = 0;
double annIncRatePercent = 0;
System.out.println("Hello, and welcome to the loan calculator");
//Acquire necessary data
System.out.println("What is the starting annual interest rate? (please enter as XX, where XX = XX%)");
startAnnInt = (scanner.nextDouble()/100);
System.out.println("What is the ending annual interest rate? (please enter as XX, where XX = XX%)");
endAnnInt = (scanner.nextDouble()/100);
System.out.println("What is the annual increment rate? (please enter as XX, where XX = XX%)");
incRate = (scanner.nextDouble()/100);
System.out.println("What is the first term for payment (in years)?");
firstYears = scanner.nextDouble();
System.out.println("What is the last term for payment (in years)?");
lastYears = scanner.nextDouble();
System.out.println("What is the term increment (in years)?");
incYears = scanner.nextDouble();
System.out.println("What is the loan amount? (in the form XXXXXX, where XXXXXX = $XXX,XXX)");
loanAmt = scanner.nextDouble();
double[] monthArray = yearToMonth(firstYears, lastYears, incYears, startAnnInt, endAnnInt, incRate);
firstMonths = monthArray[0];
lastMonths = monthArray[1];
incMonths = monthArray[2];
startMonthInt = monthArray[3];
endMonthInt = monthArray[4];
monthIncRate = monthArray[5];
monthIncRatePercent = monthArray[6];
annIncRatePercent = monthArray[7];
paymentCalc(startMonthInt, endMonthInt, monthIncRate, firstMonths, lastMonths, incMonths, loanAmt, firstYears, lastYears, incYears, startAnnInt, endAnnInt, incRate);
}
//MODULES HERE
public static double[] yearToMonth(double firstYears, double lastYears, double incYears, double startAnnInt, double endAnnInt, double incRate){
double firstMonths = 0;
double lastMonths = 0;
double incMonths = 0;
double startMonthInt = 0;
double endMonthInt = 0;
double monthIncRate = 0;
double monthIncRatePercent = 0;
double annIncRatePercent = 0;
//do our conversions
firstMonths = (firstYears * 12);
lastMonths = (lastYears * 12);
incMonths = (incYears * 12);
startMonthInt = (startAnnInt / 12);
endMonthInt = (endAnnInt / 12);
monthIncRate = (incRate / 12);
monthIncRatePercent = (monthIncRate/100);
annIncRatePercent = (incRate/100);
//put our conversions into an array
double[] monthArray = {firstMonths, lastMonths, incMonths, startMonthInt, endMonthInt, monthIncRate, monthIncRatePercent, annIncRatePercent};
//return our conversions
return monthArray;
}
public static void paymentCalc(double startMonthInt, double endMonthInt, double monthIncRate, double firstMonths, double lastMonths, double incMonths, double loanAmt, double firstYears, double lastYears, double incYears, double startAnnInt, double endAnnInt, double incRate){
double monthInt = 0;
double monthsToPay = 0;
double rowNumber = (((lastYears - firstYears))/incYears);
double rowNumberWithInt = (rowNumber + 1);
double colNumber = ((endMonthInt - startMonthInt)/monthIncRate);
double colNumberWithTop = (colNumber+1);
double currentYears = 0;
double currentMonths = 0;
double currentMonthInt = 0;
double currentPayment = 0;
double currentAnnInt = 0;
double annuityAmt = 0;
//counting columns
for (double i = 0; i <= colNumberWithTop; i++) {
//printing the top column
if (i == 0){
System.out.printf("%-10s", "Interest Rate");
for (double k = 0; k <= rowNumber; k++) {
currentYears = (firstYears + (incYears * i));
System.out.printf("%10s", currentYears + " Years"); }
} else if (i > 0) {
//finding annual interest rate for printing, and monthly interest rate as a decimal for math
currentAnnInt = (startAnnInt + (incRate * i));
currentMonthInt = ((currentAnnInt/100)/12);
System.out.printf("%.2f10s\n", (currentAnnInt * 100));
for (double k = 0; k <= rowNumber; k++) {
monthsToPay = (startMonthInt + (monthIncRate * i));
annuityAmt = annuityCalc(currentMonthInt, monthsToPay);
currentPayment = (loanAmt * annuityAmt);
System.out.printf("%.2f10s", currentPayment);
}
}
}
}
public static double annuityCalc(double monthInt, double monthsToPay){
double annuityFactor = 0;
double mirPow = 0;
mirPow = Math.pow((1+monthInt), monthsToPay);
annuityFactor = ((monthInt*mirPow)/(mirPow-1));
return annuityFactor;
}
}
EDIT:
I changed the code to
for (double i = 0; i <= colNumberWithTop; i++) {
//printing the top column
if (i == 0){
System.out.printf("%10", "Interest Rate");
for (double k = 0; k <= rowNumber; k++) {
currentYears = (firstYears + (incYears * i));
System.out.printf("%10", currentYears + " Years"); }
} else if (i > 0) {
//finding annual interest rate for printing, and monthly interest rate as a decimal for math
currentAnnInt = (startAnnInt + (incRate * i));
currentMonthInt = ((currentAnnInt/100)/12);
System.out.printf("%10.2f\n", currentAnnInt);
for (double k = 0; k <= rowNumber; k++) {
monthsToPay = (startMonthInt + (monthIncRate * i));
annuityAmt = annuityCalc(currentMonthInt, monthsToPay);
currentPayment = (loanAmt * annuityAmt);
System.out.printf("%10.2f", currentPayment);
}
And it's now giving me "java.util.UnknownFormatConversionException: Conversion = '1'"
EDIT 2:
I've changed the code to
public static void paymentCalc(double startMonthInt, double endMonthInt, double monthIncRate, double firstMonths, double lastMonths, double incMonths, double loanAmt, double firstYears, double lastYears, double incYears, double startAnnInt, double endAnnInt, double incRate){
double monthInt = 0;
double monthsToPay = 0;
double rowNumber = (((lastYears - firstYears))/incYears);
double rowNumberWithInt = (rowNumber + 1);
double colNumber = ((endMonthInt - startMonthInt)/monthIncRate);
double colNumberWithTop = (colNumber+1);
double currentYears = 0;
double currentMonths = 0;
double currentMonthInt = 0;
double currentPayment = 0;
double currentAnnInt = 0;
double annuityAmt = 0;
//counting columns
for (double i = 0; i <= colNumberWithTop; i++) {
//printing the top column
if (i == 0){
System.out.printf("%-20s", "Interest Rate");
for (double k = 0; k <= rowNumber; k++) {
currentYears = (firstYears + (incYears * i));
System.out.printf("%-20s", currentYears + " Years");
}
System.out.println();
} else if (i > 0) {
//finding annual interest rate for printing, and monthly interest rate as a decimal for math
currentAnnInt = (startAnnInt + (incRate * i));
currentMonthInt = ((currentAnnInt/100)/12);
System.out.printf("%-20.2f%%", currentAnnInt*100);
for (double k = 0; k <= rowNumber; k++) {
monthsToPay = (firstMonths + (incMonths * i));
annuityAmt = annuityCalc(currentMonthInt, monthsToPay);
currentPayment = (loanAmt * annuityAmt);
System.out.printf("%-20.2f", currentPayment);
}
System.out.println();
}
}
}
The data I'm getting back is
Interest Rate 15.0 Years 15.0 Years 15.0 Years 15.0 Years
4.25% 28235795.88 28235795.88 28235795.88 28235795.88
4.50% 26667168.53 26667168.53 26667168.53 26667168.53
4.75% 25263659.87 25263659.87 25263659.87 25263659.87
5.00% 24000502.07 24000502.07 24000502.07 24000502.07
5.25% 22857645.03 22857645.03 22857645.03 22857645.03
5.50% 21818684.11 21818684.11 21818684.11 21818684.11
5.75% 20870067.61 20870067.61 20870067.61 20870067.61
6.00% 20000502.50 20000502.50 20000502.50 20000502.50
6.25% 19200502.59 19200502.59 19200502.59 19200502.59
>
Why on earth is it doing this? It seem to be printing the interest rate under the 30 Years column and shifting all the other columns left one, and printing the first interest rate at the end of the top column
Expected output is
Interest Rate 15 Years 20 Years 25 Years 30 Years
4.0000 739.69 605.98 527.84 477.42
4.2500 752.28 619.23 541.74 491.94
4.5000 764.99 632.65 555.83 506.69
4.7500 777.83 646.22 570.12 521.65
5.0000 790.79 659.96 584.59 536.82
5.2500 803.88 673.84 599.25 552.20
5.5000 817.08 687.89 614.09 567.79
5.7500 830.41 702.08 629.11 583.57
6.0000 843.86 716.43 644.30 599.55

Issue was that when I asked you to remove the s you removed everywhere...
This should work now
for (double i = 0; i <= colNumberWithTop; i++) {
//printing the top column
if (i == 0){
System.out.printf("%-10s", "Interest Rate");
for (double k = 0; k <= rowNumber; k++) {
currentYears = (firstYears + (incYears * i));
System.out.printf("%10s", currentYears + " Years");
}
System.out.println();
} else if (i > 0) {
//finding annual interest rate for printing, and monthly interest rate as a decimal for math
currentAnnInt = (startAnnInt + (incRate * i));
currentMonthInt = ((currentAnnInt/100)/12);
System.out.printf("%10.2f%%", currentAnnInt*100);
for (double k = 0; k <= rowNumber; k++) {
monthsToPay = (startMonthInt + (monthIncRate * i));
annuityAmt = annuityCalc(currentMonthInt, monthsToPay);
currentPayment = (loanAmt * annuityAmt);
System.out.printf("%10.2f", currentPayment);
}
System.out.println();
EDITED per OP's request.

PrintStream#printf takes in a format string and objects, returning a formatted string. The format string has a certain format for numeric values:
%[argument_index$][flags][width][.precision]conversion
For example, to have a number take up 15 characters and have 2 decimal places, the follow format string would do the job:
%15.2f.
In your edit, you are missing the conversion portion of the formatted string. This is causing the UnknownFormatConversionException. Each format string MUST end with a conversion (d, f, b, s).
For example, change:
System.out.printf("%10", currentYears + " Years");
to:
System.out.printf("%10s", currentYears + " Years");
Notice the s at the end of the format string. Read more about the format string syntax at the official documentation.

Related

JAVA Looping a formula

To start, I'm a relatively new programmer as it pertains to JAVA. I've searched for many things but it's possible I'm not search for the right thing. I'm basically trying to list from the first "year" to the 10th "year" a starting amount, multiplied by the percentage, and added to the starting amount. Then, I want to take that new amount and do the same thing over and over again until it gets to 10. Or, even a specified total ex:2000.
public static void main(String[] args)
{
double startAmount = 1000;
double ratePercentage = 0.05;
double newAmount;
for (int i = 0; i <= 10; i++){
newAmount = startAmount + (startAmount * ratePercentage);
System.out.println(i + " " + newAmount);
}
}
I'm not 100% sure what you are trying to achive. But assuming you are trying to do some sort of compounding interest. This should help.
public static void main(String[] args)
{
double startAmount = 1000;
double ratePercentage = 0.05;
double newAmount;
newAmount = startAmount;
for (int i = 0; i <= 10; i++){
newAmount = newAmount + (newAmount * ratePercentage);
System.out.println(i + " " + newAmount);
}
}
Try this
public static void main(String[] args)
{
double startAmount = 1000;
double ratePercentage = 0.05;
double newAmount;
for (int i = 0; i < 10; i++){
newAmount = startAmount + (startAmount * ratePercentage);
System.out.println(i + " " + newAmount);
startAmount=newAmount;
}
}

Calculating Average and Standard Deviation using do while loop

I am trying to write a program which asks the user for a series of positive values and computes the mean and standard deviation of those values having the input stop when the user enters -1. I seem to have the average part down however. I can't seem to get the standard deviation.
So far this is what I have.
import java.util.Scanner;
public class HW0402
{
public static void main(String[] args)
{
Scanner input = new Scanner(System.in);
double x;
double sum = 0;
double average = 0;
double dev = 0;
double var = 0;
double sqrx = 0;
int n = 0;
do
{
System.out.println("Enter positive values, enter -1 to end");
x = input.nextInt();
if (x == -1)
{
break;
}
sum += x;
n++;
average = sum / n;
sqrx += Math.pow(x-average,2);
var = sqrx / (n-1);
dev = Math.sqrt(var);
} while (x != -1);
System.out.println("Average: " + average);
System.out.println("Deviation: " + dev);
}
}
I seem to get odd results such as decimals when simply calculating sqrx += x- average
I'm new to java and haven't leaned alternatives to this problem, I would love it if someone pointed me in the right direction on what I should do, or explain what I did wrong.
Apologies ahead of time for any novice mistakes I made.
int n = 0;
int K = 0;
double Sum = 0;
double Sum_sqr = 0;
do {
System.out.println("Enter positive values, enter -1 to end");
x = input.nextInt();
if (x == -1)
{
break;
}
if ( n == 0 ) K = x;
n++;
Sum += (x - K);
Sum_sqr += (x - K) * (x - K);
} while (x != -1);
double mean = K + Sum / n;
double varPop = (Sum_sqr - (Sum*Sum)/n) / (n);
double varSample = (Sum_sqr - (Sum*Sum)/n) / (n-1);
double devPop = Math.sqrt(varPop);
double devSample = Math.sqrt(varSample);
Reference Wikipedia: Computing Shifted Data. Also, Population or Sample, makes a difference.

My program wont go past my first few lines of code

So I'm pretty new to this site, but you guys are my last hope. The goal here is that a user will input 10 temperatures in Fahrenheit (enter -999 to stop while entering) then the program will change those temps into Celsius. Also the user will need to type in their location. I am able to type in the location, but after I hit 'Enter' I get:
Exception in thread "main" java.util.InputMismatchException
at java.util.Scanner.throwFor(Unknown Source)
at java.util.Scanner.next(Unknown Source)
at java.util.Scanner.nextInt(Unknown Source)
at java.util.Scanner.nextInt(Unknown Source)
at Prog1.main(Prog1.java:20)`
Here is my code:
import java.util.Scanner;
public class Prog1
{
public static void main(String[] args){
Scanner in = new Scanner(System.in);
//asks the user for the location
System.out.print("Enter Location: ");
int place = in.nextInt();
System.out.print(place);
double[] temp = new double[10];
int num = 0;
//prime the loop
System.out.print("Enter temperature: ");
int input = in.nextInt();
//get up to 10 temperatures and store in array "temp"
while (input >= -998 && num < 10) {
temp[num] = input;
num++;
System.out.print("Enter temperature: ");
input = in.nextInt();
}
//print report
System.out.println();
System.out.printf("%5s %5\n", "Fahrenheit", "Celcius");
for (int x = 0; x < num; x++) {
System.out.printf("%5d %5s\n", temp[x], celsius( temp[x]));
}
System.out.printf("\nHigh: %6.2f", max( temp, num));
System.out.printf("\nLow: %6.2f", min( temp, num));
System.out.printf("\nAverage: %6.2f", average(temp, num));
}
/**
* Method to convert farenheit to celsius
* #param double farenheit temperature
* #return double celsius temperature
*/
public static double celsius(double input) {
double celcius = 5.0 / 9.0 * ( input - 32);
return celcius;
}
/**
* Method to calculate average, min and max temperatures
*
* #param double farenheit temperature
* #return average, min and max temperatures
*/
public static double average(double[] temp, int num) {
double sum = 0;
for (int x = 0; x < num; x++) {
sum += temp [x];
}
return (double) sum / num;
}
public static double max( double[] temp , int num){
double max = temp[0];
for (double x : temp) {
if (max > num) {
max = num;
}
return num;
}
return max;
}
public static double min(double[] temp, int num) {
double min = temp[0];
for (double x : temp) {
if (min < num) {
min = num;
}
return min;
}
return num;
}
}
You're getting an InputMismatchException, which means that whatever the user is submitting to you is of a different type then you have programmed for.
You ask for the user to input their location, and then call in.nextInt(). nextInt() will throw an exception if the next token in the standard input is not an integer. You must be entering something other than an integer for the location which is throwing the exception. If you want to enter a text based location (like a String) try in.nextLine()
InputMismatch Exceptions are thrown when you put a datatype somewhere that was expected to be a different datatype. Since you are working with degrees, I'm assuming you might be entering floating point values, so in.nextDouble() might be a better option than in.nextInt(). You can then cast it to an integer later if you want that to be your output.
I've run your code just to see what is going on. You were not formatting printf correctly. Replace this part it'll do.
//print report
System.out.println();
System.out.printf("%s %s\n", "Fahrenheit", "Celcius");
for (int x = 0; x < num; x++) {
System.out.println(temp[x] + "\t" +celsius(temp[x]) );
}
I find this quick guide useful : http://web.cerritos.edu/jwilson/SitePages/java_language_resources/Java_printf_method_quick_reference.pdf
The solution above is quite a simple one.You have to replace:
System.out.print("Enter Location: ");
int place = in.nextInt();
System.out.print(place);
with
System.out.print("Enter Location: ");
String place = in.nextLine();
System.out.print(place);
since location is a string,when you give something like 'India' in.nextInt() would be expecting a number instead of string.So you were getting that error.Replace it only below enter location sysout.
replace formatting too. try this :
import java.util.Scanner;
public class Prog1
{
public static void main(String[] args){
Scanner in = new Scanner(System.in);
//asks the user for the location
System.out.print("Enter Location: ");
String place = in.nextLine();
System.out.print(place);
double[] temp = new double[10];
int num = 0;
//prime the loop
System.out.print("Enter temperature: ");
int input = in.nextInt();
//get up to 10 temperatures and store in array "temp"
while (input >= -998 && num < 10) {
temp[num] = input;
num++;
System.out.print("Enter temperature: ");
input = in.nextInt();
}
System.out.println();
System.out.printf("%s %s\n", "Fahrenheit", "Celcius");
for (int x = 0; x < num; x++) {
System.out.println(temp[x] + "\t" +celsius(temp[x]) );
}
System.out.printf("\nHigh: %6.2f", max( temp, num));
System.out.printf("\nLow: %6.2f", min( temp, num));
System.out.printf("\nAverage: %6.2f", average(temp, num));
}
/**
* Method to convert farenheit to celsius
* #param double farenheit temperature
* #return double celsius temperature
*/
public static double celsius(double input) {
double celcius = 5.0 / 9.0 * ( input - 32);
return celcius;
}
/**
* Method to calculate average, min and max temperatures
*
* #param double farenheit temperature
* #return average, min and max temperatures
*/
public static double average(double[] temp, int num) {
double sum = 0;
for (int x = 0; x < num; x++) {
sum += temp [x];
}
return (double) sum / num;
}
public static double max( double[] temp , int num){
double max = temp[0];
for (double x : temp) {
if (max > num) {
max = num;
}
return num;
}
return max;
}
public static double min(double[] temp, int num) {
double min = temp[0];
for (double x : temp) {
if (min < num) {
min = num;
}
return min;
}
return num;
}
}

How to Calculate Avg and how to allow only positive user input values for data in java?

I am looking to find a simple beginner way to add code that If any input is negative, the program should prompt user again until  they  input  a  non‐negative  value. I also not sure how to calculate the avg only for the days that the distance is not 0.0 miles. I know that the if‐statement should check if x is within some value (say ±0.0001) from 0.0. Because using the statement  if (x == 0.0)  would  evaluate to a false  because the value is not stored precisely.
import java.util.Scanner;
import java.lang.Math;
public class Lab3_1
{
public static void main(String[] arg)
{
String[] Day = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};
double[] Time = new double[7];
double[] Distance = new double[7];
double[] MPH = new double[7];
Scanner input = new Scanner(System.in);
for(int i = 0; i < Day.length; i++)
{
System.out.println("Data for " + Day[i]);
System.out.print("Input Time in minutes");
Time[i] = input.nextDouble();
System.out.print("Input Distance in miles");
Distance[i] = input.nextDouble();
}
for(int s = 0; s < Day.length; s++)
{
MPH[s] = (double)Distance[s] / ((double)Time[s] / 60);
}
double max = MPH[0];
for (int i = 1; i < Day.length; i++)
{
if (MPH[i] > max)
{
max = MPH[i];
}
}
double min = MPH[0];
for (int i = 1; i < Day.length; i++)
{
if (MPH[i] < min)
{
min = MPH[i];
}
}
double MPHsum = 0.0;
for(int i = 0; i < Day.length; i++)
{
MPHsum = MPHsum + MPH[i];
}
double avg = 0;
avg = (double)MPHsum / Distance.length;
System.out.println("Sum of values is " + MPHsum);
System.out.println("Minimum pace in MPH " + min);
System.out.println("Maximum pace in MPH " + max);
System.out.println("Average pace in MPH " + avg);
}
}
for(int i = 0; i < Day.length; i++)
{
System.out.println("Data for " + Day[i]);
System.out.print("Input Time in minutes");
Time[i] = input.nextDouble();
while(Time[i] < 0){
System.out.println("Invalid input, try again: ");
Time[i] = input.nextDouble();
}
System.out.print("Input Distance in miles");
Distance[i] = input.nextDouble();
while(Distance[i] < 0){
System.out.println("Invalid input, try again: ");
Distance[i] = input.nextDouble();
}
}
Here I have created a loop which runs till Time[i] is less then 0, asking user to input new values again and again till a positive value is entered. Same thing for Distance.
If you want to repeat the question until the response is valid then do while is likely more appropriate than while:
do {
System.out.println("Input distance");
distance[i] = input.nextDouble();
if (distance[i] < 0.0)
System.out.println("Invalid entry");
} while (distance[i] < 0.0);
If you are using Java 8 then there's a far simpler way of filtering and averaging:
Arrays.stream(distance).filter(d -> d > 0.0).average();
That returns an OptionalDouble because you can't be sure there is an average (e.g. all the distances might be 0). You can use ifPresent and getAsDouble to use the value.
You can replace average with sum, count, max to retrieve other statistics. Or you can get all the statistics in one go:
DoubleSummaryStatistics stats = Arrays.stream(distance)
.filter(d -> d > 0.0).summaryStatistics();
Then you can use stats.getAverage, stats.getMin, stats.getSum to retrieve the various statistics.
Exactly the same method can be used for getting statistics on mph or any other array.

Adding last average value

I'm having trouble adding the last number of the loop that I have. I don't have any ideas how to include the last number and then add it to the double variable and then divide it to make the average. I would use my IDE to solve the problem but the input has to be approximately 1000 trials in order to be accurate. You can plainly see that 10 trials of 3.0 or higher does not equal approximately 2.8. I just need to have the missing trial added and then calculated into the average.
Code:
import java.util.*;
public class CalculatePI2
{
public static boolean ifitisInside (double xPosion, double yPosion)
{
double distance = Math.sqrt((xPosion * xPosion) + (yPosion * yPosion));
return (distance < 1.0);
}
public static double calculatePI (int numThrows)
{
Random randomGen = new Random();
int hits = 0;
double PI = 0;
double Alpha=0;
double average= 0;
for( int m=0; m<10; m++)
{
Alpha=+PI;
average= m/Alpha;
if(m>=0)
{
hits=0;
PI=0;
for (int i = 0; i <= numThrows; i++)
{
double xPosion = (randomGen.nextDouble()) * 2 - 1.0;
double yPosion = (randomGen.nextDouble()) * 2 - 1.0;
if (ifitisInside(xPosion, yPosion))
{
hits++;
double dthrows = numThrows;
PI =+ (4.0 * (hits/dthrows));
}
}
System.out.println("Trial["+m+"]: ="+ PI);
}
}
System.out.println("Estimate:"+average);
return PI;
}
public static void main (String[] args)
{
Scanner pie = new Scanner (System.in);
System.out.println("This program approximates PI using the Monte Carlo method. By simulating throwing darts at a dartboard. ");
System.out.print("Please enter number of throws: ");
int numThrows = pie.nextInt();
double PI = calculatePI(numThrows);
}
}
Just take the average computation out of the inner loop. Also, the loop invariant is from 0 to < numthrows, not <= numthrows. Also, your initialization of the variables needs to happen for each of your 10 trials, so it needs to be moved inside the loop.
double sumPiOverMTrials = 0;
for( int m=0; m<10; m++)
{
double hits = 0;
for (int i = 0; i < numThrows; i++) {
double xPosition = (randomGen.nextDouble()) * 2 - 1.0;
double yPosition = (randomGen.nextDouble()) * 2 - 1.0;
if (ifitisInside(xPosition, yPosition))
{
hits++;
}
}
double pi = 4.0 * hits/numthrows;
System.out.println("Trial["+m+"]: ="+ pi);
sumPiOverMTrials += pi;
}
System.out.println("Average over "+m+" trials ="+ sumPiOverMTrials/10);
I think you can solve this just by rearranging your code:
public static double calculatePI (int numThrows)
{
Random randomGen = new Random();
int hits = 0;
double PI = 0;
double Alpha=0;
double average= 0;
for( int m=0; m<10; m++)
{
for (int i = 0; i <= numThrows; i++)
{
double xPosion = (randomGen.nextDouble()) * 2 - 1.0;
double yPosion = (randomGen.nextDouble()) * 2 - 1.0;
if (ifitisInside(xPosion, yPosion))
{
hits++;
double dthrows = numThrows;
PI += (4.0 * (hits/dthrows)); // NOTE: += not =+
}
}
Alpha+=PI; // NOTE += not =+
average= m/Alpha;
if(m>=0)
{
hits=0;
PI=0;
}
System.out.println("Trial["+m+"]: ="+ PI);
}
}
This way the average is calculated after each trial rather than before. Also, I don't know much about this particular algorithm, but I think that this line:
average=m/Alpha;
should be:
average=Alpha/m

Categories