Formatting of double to not include decimal places - java

The code below is what I have. I am a fairly new programmer going through my first Java class so bear with me.
import salespersonannualcomp.SalespersonCompensationAnnualCalculator;
import java.util.Scanner;
public class SalespersonAnnualSalesInput
{
public static void main( String[] args)
{
Scanner input = new Scanner( System.in );
//Instantiates a new instance of SalespersonCompensationAnnualCalculator
SalespersonCompensationAnnualCalculator myAnnualSales = new SalespersonCompensationAnnualCalculator();
//Prompt for and input total annual sales
System.out.println( "Please enter the total annual sales:" );
String yearlySalesString = input.nextLine();
//Declares yearlySalesInt as the variable that will store the results of Integer.parseInt
int yearlySalesInt = Integer.parseInt(yearlySalesString);
//Declares calcResults as the variable that will store the value created by the calcAnnualCompensation method
double calcResults = myAnnualSales.calcAnnualCompensation(yearlySalesInt);
//Displays the result of the calculations done for determining total annual compensation
System.out.println(" Total Annual compensation is $"+ calcResults);
System.out.println();
System.out.println(" Total Potential Annual Compensation Chart");
for(double potentialAnnualSales = yearlySalesInt;potentialAnnualSales<=(1.5*yearlySalesInt);potentialAnnualSales=potentialAnnualSales+5000)
{
double calcAnnualCompensation=myAnnualSales.calcAnnualCompensation(potentialAnnualSales);
System.out.printf( "%f %f%n ",potentialAnnualSales,calcAnnualCompensation);
}
}
}
The resulting output looks like this.
Total Annual compensation is $60400.0
Total Potential Annual Compensation Chart
160000.000000 60400.000000
165000.000000 60725.000000
170000.000000 61050.000000
175000.000000 61375.000000
180000.000000 61700.000000
185000.000000 62025.000000
190000.000000 62350.000000
195000.000000 62675.000000
200000.000000 63000.000000
205000.000000 63325.000000
210000.000000 63650.000000
215000.000000 63975.000000
220000.000000 64300.000000
225000.000000 64625.000000
230000.000000 64950.000000
235000.000000 65275.000000
240000.000000 65600.000000
I would like for it to not display the decimal places, and for all the lines to align correctly. I have the output correct but I'm struggling with the formatting.

You are close...
If you want no places after the decimal, and to line it up:
System.out.printf( "%10.0f %10.0f%n ",potentialAnnualSales,calcAnnualCompensation);
If you want two places after the decimal:
System.out.printf( "%10.2f %10.2f%n ",potentialAnnualSales,calcAnnualCompensation);
Essentially, 10.2f means 10 spaces to the left of the decimal (using spaces for padding) and 2 after. Similarly, 6.0f would mean 6 spaces to the left of the decimal and none after. You'll have to play with the number of spaces for your specific use case.

Use either:
new DecimalFormat("#").format(d)
Or:
(int)Math.round(d)

In general using double's for monetary calculations is a bad practice. Instead use BigDecimal. To get rid of the trailing decimals call setScale(0); on your instance. For better formatting use NumberFormat.

You can tell printf how many decimal places to print as well as how wide to make each field. The syntax is like so: %<WIDTH>.<PRECISION>f where <WIDTH> and <PRECISION> are to be replaced by non-negative integers. Both numbers are optional and you can leave them out if you want the defaults.
Here I am printing some random numbers with column width of 10 characters and a precision of 2 decimal places.
public class Test {
public static void main(String[] args) {
for (int i = 0; i < 6; ++i) {
System.out.printf("%10.2f%10.2f%10.2f%10.2f%n",
100000.0 * Math.random() * Math.random(),
100000.0 * Math.random() * Math.random(),
100000.0 * Math.random() * Math.random(),
100000.0 * Math.random() * Math.random());
}
}
}
Possible Output:
72411.07 11074.66 4722.24 74523.64
264.89 54015.77 53969.66 61229.94
5386.74 7939.65 47678.67 24953.68
4985.14 17769.77 17345.57 38392.68
4841.93 4103.14 3581.99 74036.73
52477.30 1846.34 35547.62 10065.36
If I change the format specifiers from %10.2f to %10.0f it will only print the integral part and I might get the following output instead:
42116 26756 3293 7957
1693 23516 83116 39032
3981 40417 53635 19735
53504 77468 12341 16178
4424 81325 79304 5460
23825 6004 16507 37537
For more advanced features of printf, see the documentation of java.util.Formatter.

Related

DecimalFormat.format method call: incompatible types

I wanted to know why there is an error and how to fix it for my java project.
I have to make exactly same out as these:
What is your annual interest rate as a decimal? (ex: 0.045): .033
How many years will your mortgage be held? 15
What amount of the mortgage did you borrow? 300000
The number 0.033 can be represented as 3.3%
The mortgage amount is $300,000.00
The monthly payment in dollars is $2,115.30
The total payment in over the years in dollars is $380,754.76
The over-payment is $80,754.76 The over-payment as a percentage of
the mortgage is 26.9
And this is what I did on Eclipse;
double annIntRat;
int nOY;
int borrowMor;
int M;
double monthPay;
double mIR;
Scanner scnr = new Scanner(System.in);
// Your code should go below this line
System.out.print("What is your annual interest rate as a decimal? (ex 0.045): ");
annIntRat = scnr.nextDouble();
System.out.print("How many years will your mortgage be held? ");
nOY = scnr.nextInt();
System.out.print("What amount of the mortgage did you borrow? ");
borrowMor = scnr.nextInt();
DecimalFormat df = new DecimalFormat("0.0");
System.out.println("\nThe number "+annIntRat+" can be represented as "+df.format((annIntRat)*100)+"%");
NumberFormat defaultFormat = NumberFormat.getCurrencyInstance();
M=defaultFormat.format(borrowMor); //< Here is the error and tells me to change to String.But if I do so, there will be an error down there for monthPay=.....
System.out.println("The mortgage amount is "+M);
mIR=(annIntRat)/12;
monthPay=(mIR * M)/(1-(1/Math.pow(1+mIR,12*nOY)));
It took me a while to see where you highlighted your error, I would recommend being more explicit with where your errors are.
The 'format' method of NumberFormat you are using returns a type of String, which would explain your error.
The following should do the trick, although you can't be certain that a user is to input an integer...take that in mind.
M = Integer.parseInt(defaultFormat.format(borrowMor));
The DecimalFormat.format(long) method is an inherited method from the NumberFormat class — NumberFormat.format(long). The method returns an instance of String.
So, just use an instance of the String type to store and use the return value of the method:
String borrowMorString = defaultFormat.format(borrowMor);
System.out.println("The mortgage amount is " + borrowMorString);
// …
monthPay = (mIR * borrowMor) / (1 - (1 / Math.pow(1 + mIR, 12 * nOY)));

Incrementing with a fraction based on user input

I'm having trouble i need to take a user input and increment it by 1/10 starting at 0 so if the user enters a 5.2 i need to to go through 0.1 0.2 0.3 etc display each and stop at 5.2 until the method is called again and a new input is entered here is what i have but it just runs through up until 10 i understand why it does this just not enough to be able to fix this any help would be appreciated
import java.util.Scanner;
public class SpeedChange {
public double startSpeed;
public double newSpeed;
public void changeUserSpeed(){
Scanner sc = new Scanner (System.in);
System.out.println("How fast would you like to go between 1-10 mph?");
double newSpeed = sc.nextDouble();
for(newSpeed = sc.nextDouble(); newSpeed <= 10.00; newSpeed+=.1 ){
System.out.println(newSpeed);
}
}
}
You need to change your loop content.Since your newSpeed has been specified by the user,you don't need to alter it.You simply need to create a new double variable,say Speed,which will increment in the limit of 0.1 at each iteration and keep running until your Speed equals newSpeed.
for(double Speed=0;Speed<=newSpeed;Speed+=0.1 ){
System.out.println(Speed); }
I hope this clears and solves your doubt!
Your code should instead be
for(double speed=0; speed <= newSpeed; speed+=.1 ){
System.out.println(speed);
}
P.S: double/float is not suitable for this kind of use. Use BigDecimal class to do this.
For details, see http://javarevisited.blogspot.in/2012/02/java-mistake-1-using-float-and-double.html?m=1

Shipping Program

So I seem to have put together majority of this program correctly. Ask I skim through I realized I missed something and go back and add it in. Now as I run the program for a final test I realize that it is no longer calculating the miles correctly. I input 500 for example and will get 1 in return for number of miles shipped.
input = JOptionPane.showInputDialog("Enter package weight: ");
weight = Double.parseDouble(input);
input = JOptionPane.showInputDialog("Enter approximate miles package is being shipped: ");
miles = Integer.parseInt(input);
miles = (miles+499)/500;
input = JOptionPane.showInputDialog("Enter number of units shipped: ");
units = Integer.parseInt(input);
I know I am not doing the math correctly in order to find the correct amount charged per unit but what is concerning for now is the miles being shown incorrectly in my output. Any suggestions? Thanks!
Assuming miles is declared as double (if it's not, you should declare it as double so you can assign it a real number). This line
miles = (miles+499)/500;
is making a integer division (int/int = int). To get a double, you must cast it:
miles = (double)(miles+499)/500;
or, as #Vulcan suggested
miles = (miles+499)/500.0; // here 500.0 is a double
It seems like the data type of miles variable is int.Please change it to double and re-run the application.
Also as per ur comment updating the logic :
Let the input you entered is :
double weight = 7; //input
double miles = 550; //input
double unit = 2; //input
double charges =0; //charge of the shipment initialise with 0
charges = (3.70*miles*unit*weight)/(500*7);
System.out.println("The charges is "+charges);
The charges of 1 unit is $3.70 per 7 pound weight per 500 miles.
Also update the existing code :
miles = Integer.parseInt(input); //Use double as conversion
miles = (miles+499)/500; // remove the line

giveChange method computes change and number of coins to return java?? [duplicate]

This question already has answers here:
min change greedy algorithm in java
(2 answers)
Closed 8 years ago.
I have a cashregister program that inputs purchases and payment and outputs the change due. i need it to not give just an amount but what particular coins/dollars user should get back. heres two methods i have
public void recordPurchase()
{
System.out.print("Enter total purchase price or negative number to end: ");
double input = keyboard.nextDouble();
while(input > 0)
{
purchase = purchase + input;
System.out.print("Enter total purchase price or negative number to end: ");
input = keyboard.nextDouble();
}
}
public double giveChange(Money moneyTypes)
{
double change = payment - purchase;
purchase = 0;
payment = 0;
//computes change rounding to two decimal places
change = (double)(Math.round(change*100))/100;
return change;
}
I need to output what coins/dollars person should get back. i have the money types saved in an array called moneyTypes. for example if the change due is $1.06 it would output you receive a dollar nickel and penny.
any advice would help. Thanks! if you need to see more of the code let me know
I'll give you an advice how to do it, not a solution.
Make a list of possible coin/note values.
Then from the biggest to lowest, compute how many times it fits into the remainder, and subtract this amount of money from the value. Make a note of the number of coins/notes.
This way, you will get the numbers you need.
count = Math.floor(remainder/coinValue) might help you.

exponential growth in java, return type array of doubles

Im working on a CS assignment and Im having a little trouble understanding how to output an array of doubles that represent the amt of money in a bank account at increments of time given a user specified growth rate. I have a main method that asks the user for initialAmount of $, a growthRate and the number of time intervals (denoted iA, gR and nP for inital Amount, growth Rate and number of Periods). this method then calls another method which is of return type double[]. My issue is with the code inside my for-loop, it compiles fine but outputs gibberish. heres the code:
import java.util.Scanner;
public class Benford {
public static double[] generateBenfordNumbers (double iA, double gR, int nP) {
double[] bankStatement = new double[nP];
for (int i = 0; i<nP; i++) {
bankStatement[i] = (iA*(Math.pow((1+(gR)), (i++))));
}
return bankStatement;
}
public static void main (String[] args) {
Scanner scan = new Scanner(System.in);
double iA;
double gR;
int nP;
System.out.print("What is the initial amount of money that you are starting with? : ");
iA = scan.nextDouble();
System.out.println();
System.out.print("What is the amount of growth per time period? : ");
gR = scan.nextDouble();
System.out.println();
System.out.print("How many time periods would you like to use? : ");
nP = scan.nextInt();
System.out.println();
generateBenfordNumbers(iA, gR, nP);
System.out.print(generateBenfordNumbers(iA, gR, nP));
}
}
In the line
bankStatement[i] = (iA*(Math.pow((1+(gR)), (i++))));
i++ increments i a second time. You probably want:
bankStatement[i] = (iA*(Math.pow((1+(gR)), i + 1)));
or, if we clean it up,
bankStatement[i] = iA * Math.pow(1 + gR, i + 1);
i + 1 returns a value 1 greater than that of i, but does not actually increment the variable itself.
Also, do you really have to use Math.pow each time? Can't you just manually set the first element of your array to iA and subsequently use bankStatement[i-1] to compute bankStatement[i]? Doing something like this will probably improve your program.
i is incremented twice : at loop level and into the body
The gibberish output looks like this:
[D#1b67f74
which is s double array text representation. You could use:
System.out.print(Arrays.toString(generateBenfordNumbers(iA, gR, nP)));
You should not be incrementing i inside your call to Math.pow. This is because you already increment it in your for loop. The result is that elements of your array are getting skipped and not set. This is probably where the gibberish-ness is coming from.
You probably want to change:
bankStatement[i] = (iA*(Math.pow((1+(gR)), (i++))));
To:
bankStatement[i] = iA*Math.pow(1+gR, i);
Also, as an aside, you generally shouldn't use so many parenthesis because it makes it hard to read. If you're not sure what the order of operations is, look it up.
What the others said, you're incrementing i twice so I'm not going to repeat that. I just want to add that brackets are good to organize formulas and to ensure correct execution order of calculations, but if you overuse them, they can obfuscate the intention of your program and they may make the problem you're looking for harder to spot. Compare
bankStatement[i] = iA * Math.pow(1.0 + gR, i+1);
with
bankStatement[i] = (iA*(Math.pow((1+(gR)), (i))));
See what I mean?
EDIT - following ARS very valid remark about the initial value of i, I changed the cleaned up statement.

Categories