Java correct order of operations - java

I have written this operation on paper and it works just fine. I know that java the execution is from left to right and the precedence is like this; * / + - .
Java gives me a different result, but i cant figure out why.
public double overTimeWage() {
if (hours > 40) {
return (40 * baseRate) + (1.5 * baseRate)
* (hours - 40);
} else {
return 0;
}
}
Here's the inputs I'm using
int hours = 50;
double baseRate = 12;
as it stands it currently returns 660 , my expected return is 180.
I know this is the correct mathematical formula is because i worked it on paper. and i get 180 out of it.

660 is the expected return value. Your problem is that you added in an extraneous piece of the puzzle.
Judging by the name of your method, overTimeWage, it's supposed to calculate the amount of overtime of the worker, which is (overtimeMult * baseRate) * (hours - standardHours). In your case, (1.5 * baseRate) * (hours - 40).
The mathematical calculations go as follows:
(1.5 * baseRate) * (hours - 40)
(1.5 * 12 ) * (50 - 40)
(18 ) * (10 )
18 * 10
180
So we got the right answer, right? So why is your method returning 660 and not 180? Here's the thing, your method doesn't return (1.5 * baseRate) * (hours - 40). It returns (40 * baseRate) + (1.5 * baseRate) * (hours - 40).
See the problem? You're not returning the overtime earnings. You're returning their earnings for the whole day. Just to be clear, let's put this together again:
(40 * baseRate) + (1.5 * baseRate) * (hours - 40)
We already know that (1.5 * baseRate) * (hours - 40) = 180.
(40 * baseRate) + 180
(40 * 12) + 180
480 + 180
660
660. And there's your problem. It's the classic issue of code doing what you tell it to, not what you want it to.

If you just want the overtime:
return (1.5 * baseRate) * (hours - 40);
The way it's written for you, you're returning the ENTIRE pay, not just the overtime.

Related

How to check if a number has decimal places to the thousandths place or more?

I am working on a program that prints out the wages earned by workers including overtime pay. I am almost finished with the program. However, I am stuck on how to make a condition to fix the decimals in the wages to only the tenths and hundredths places (.00).
The condition I want is, if the number of hours worked is greater than 40 and the overtime wages have numbers in the thousandths place or more (overTimeWages has .000 or more .0000000000....), then System.out.println("$" + (Math.floor(overTimeWages * 100) / 100)); to round overTimeWages to the nearest hundredths down. I only want the tenths and hundredths place values. Else if hours worked is greater than 40 and the overtime wages have numbers only in the tenths and hundredths place, then System.out.println("$" + overTimeWages + 0);.
How do I make that condition above?
I tried overTimeWages % 0.1 != 0; but it did not work.
Below in the code comments are the values that are supposed to be inputted.
Code
import java.util.Scanner;
int payRateInCents, payRateInDollars,
hoursWorked,
overTimeHours, grossPayWithInt;
double grossPay, payRCents, payRDollars, overTimeRate;
grossPay = (double) ((payRDollars * hoursWorked));
grossPayWithInt = (payRateInCents * 40);
double grossPayWithOverTime = (double) ((grossPayWithInt) + (overTimeRate * overTimeHours));
double overTimeWages = (double) (grossPayWithOverTime / 100);
/**
2000 45 = (2000 * 40) + ((2000 * 1.5) * (45 - 40)) == 95000
2000 45 = (grossPayWithOverTime) + ((overTimeRate) * (overTimeHours)) == 95000
Then divide by 100.
2000 40 should get: $800.00
1640 41 should get: $680.60
3111 43 should get: $1384.39
1005 1 should get: $10.05
**/
if(hoursWorked > 40) {
if(overTimeWages % 0.1 != 0) {
System.out.println("$" + (Math.floor(overTimeWages * 100) / 100));
} else {
System.out.println("$" + overTimeWages + 0);
}
}
else {
if(hoursWorked < 10) {
System.out.println("$" + grossPay);
} else {
System.out.println("$" + grossPay + 0);//40 or lower
}
}
Dont use fractions or float for any variables that will hold money. Operations on float will give you unexpected result due to how floats are stored. You think 1.2 is 1.2 but it might be actually 1.19999999. That's how floats work.
I would suggest to not get into any fractions when dealing with money. Instead of 1.30$ use 130 cents.
For displaying purposes converting it is trivial:
private static DecimalFormat df = new DecimalFormat("#.##");
Syste.out.println(df.format(yourDouble));
To see how many decimals number has.
String[] split = yourDouble.toString().split("\\.");
split[0].length();
split[1].length();

Calculating Loan Interest and Duration of loan. Java

The following 2 methods are intended to calculate the length of loan(number of monthly payments that have to be paid and the interest due in the loan, respectively, given the parameters in which r is the monthly interest rate(APR), A is the loan amount(principal), P is the monthly payment and N is the number of payments that need to be made. However neither of the methods calculate correctly. How do I fix them so that they provide the number of months the payment must be made and the interest accrued?
public static double loanLength(double r, double A, double P){
double N = (Math.log(1 / (1 - ((r * A) / P)))) / Math.log(1 + r);
return N;
}
public static double loanInterest(double P, double N, double A){
double I = ((P * N) - A);
return I;
}
According to your example input it's just an arithmetic error.
The line double N = (Math.log(1 / (1 - ((r * A) / P)))) / Math.log(1 + r); has some calculations in it. The one that fails (or results in NaN) is Math.log(1 / (1 - ((r * A) / P))).
If we insert the example values: Math.log(1 / (1 - ((0.1 * 10000) / 500))) and we calculate that out:
1. Math.log(1 / (1 - ((0.1 * 10000) / 500)))
2. Math.log(1 / (1 - (1000 / 500)))
3. Math.log(1 / (1 - 2))
4. Math.log(1 / -1)
5. Math.log(-1) // <-- here happens the error
A logarithm of a number smaller/equals than 0 is not defined. So your equation is wrong
This site explains that the interest rate and payment have to be for the same period.
I guess in your case 10% is per year, while 500 is per month. So you need to divide 10 or multiply 500 by 12 to make them fit together. Otherwise, your calculation will give you the duration for a loan with 10%/500payment per month or per year (or any duration really), which can never be payed back: in every period there is 1000 interest, but only 500 payment.
Hence, log(-x) produces NaN, meaning you can never pay back.

display monthly payment in pow(a,b) method

The formula to compute the monthly payment is as follows:
monthlyPayment = (loanAmount x monthlyInterestRate) / (1 – (1 / (1 + monthlyInterestRate)numberOfYears x 12 ))
In the above formula, you have to compute (1 + monthlyInterestRate)numberOfYears x 12 ). The pow(a,b) method in the Java API Math class can be used to compute ab.
so how to put this in pow(a,b) method ?
The javadoc for the java.lang.Math class might help you here. Is there something specific you don't understand about that?
So the code to compute the b power of a should look something like this:
double result = Math.pow(a, b);
The formula you have does not look quite right. From Exact_formula_for_monthly_payment The formula should be
P= (L i)/(1- 1/(1+i)^n )
Where L is the loan amount, i is the monthly interest, and n number of periods. In your formula
monthlyPayment = (loanAmount x monthlyInterestRate) / (1 – (1 / (1 + monthlyInterestRate)numberOfYears x 12 ))
the exponential sign has been missed out. I think you want
monthlyPayment = (loanAmount x monthlyInterestRate) / (1 – (1 / (1 + monthlyInterestRate) ^ (numberOfYears x 12) ))
To calculate this in java you would want
monthlyPayment = (loanAmount * monthlyInterestRate) /
(1 – (1 / Math.pow(1 + monthlyInterestRate,numberOfYears * 12)));
Which could be simplified to
monthlyPayment = (loanAmount * monthlyInterestRate) /
(1 – Math.pow(1 + monthlyInterestRate,-numberOfYears * 12));
using a negative exponent.

Printing a Sine Wave to the Console

I'm working on a Java program that prints a sine wave to the console. This is what I've written so far:
int num = 7;
for (double y = 2; y >= 0; y-=0.2) {
for (double x = 0; x <= num; x+=0.2) {
if ( ((0.1+x) >= Math.asin((double)y-1)) && (((double)x-0.1) <= Math.asin((double)y-1)) )
System.out.print('*');
else
System.out.print(' ');
}
System.out.println();
}
Essentially, this program treats each character on each line as a 0.2 x 0.2 area on a coordinate plane. If the sine function crosses this area, an asterisk is printed to the screen. Otherwise, a space is printed.
When run, this is printed to the console:
*
*
*
*
*
*
Can anybody tell me why my program stops after printing the first quarter of the wave?
The reason it only prints the first quarter of the sine wave is because of the indicated range of Math.asin:
Returns the arc sine of a value; the returned angle is in the range -pi/2 through pi/2.
Once you advance x past Math.PI / 2, then the if statement's condition will always be false.
You can take advantage of the fact that
sin(π - x) = sin(x)
and
sin(2π - x) = -sin(x)
by including more conditions. (I've also removed the unnecessary casts to double for clarity.)
if ( (0.1+x >= Math.asin(y-1)) && (x-0.1 <= Math.asin(y-1)) ||
(0.1+x >= Math.PI - Math.asin(y-1)) && (x-0.1 <= Math.PI - Math.asin(y-1))
(2*Math.PI -(0.1 + x) <= -Math.asin(y-1)) && (2*Math.PI -(x-0.1) >= -Math.asin(y-1)) )
Output:
*
* *
* *
* * *
* * *
* * *
* *
* *
* *
* *
*
The problem seems to arise from the condition of your if-statement, which almost always evaluates to false. You should check the calculus behind your conditional expression. I find increasing num does not really help here.
Maybe you should print another character instead of a whitespace by replacing System.out.print(' '); with System.out.print('_'); for instance. This way you may be able to figure out why your program behaves that way. Reworking that algorithm of yours may also be helpful.
Edit: Whoops, skimmed the code a little too fast. This is wrong.
Well, you set num to 7, then in your loop you take x from 0 to num-1, so you're only looping over 7 columns. Increase num and your graph should add additional columns. You'll have to increase the range of y values you loop over too, if you want the graph to extend to negative numbers.
However, your algorithm is extremely inefficient. You're calculating asin(y-1) twice for every square on your graph, when all you really need to do is calculate sin(x) once for every column. Why not just fill an array with precalculated sine values and then consult the array while drawing the graph? (I realize, of course, that on a modern computer it's fast enough to be practically irrelevant either way.)
Thank you all for the help! Based on #dasblinkenlight's suggestion to use sin instead of asin, I found a very simple solution:
int num = 7;
for (double y = 1; y >= -1; y-=0.2) {
for (double x = 0; x <= num; x+=0.2) {
double sin = Math.sin(x);
if ( (0.1+y) >= sin && (y-0.1) <= sin )
System.out.print('*');
else
System.out.print(' ');
}
System.out.println();
}
This prints this to the console:
*****
** *
* **
* * **
* * *
* * *
* *
* *
* *
** **
****

Need help porting this equation to java

I'm trying to make a program that calculates the required score to level in a game and the equation works fine on my calculator but not when i try changing it to work with java.
the equation is 5,000 / 3 * (4n^3 - 3n^2 - n) + 1.25 * 1.8^(n - 60) for example level 49 you should need to have a total score of 772240000 points and the calculator gives this answer but my java program doesn't. here is the code i tried.
for (int i = 0; i <= 100; i++) {
double score = (double) ((5000 / 3) * (Math.pow(4 * i, 3) - Math.pow(3 * i, 2) - i) + (1.25 * Math.pow(1.8, i - 60)));
System.out.println("Level " + i + " requires " + (long) score);
}
This doesnt seem to work right and gives 12513130000 as the required points for lvl 49. If anyone can get it to work would you miind explaining what i did wrong.
You're messing up your Math.pow calls, but you can avoid some of them entirely:
double score = (double) ((5000 / 3) * (4 * i * i * i - 3 * i * i - i) + (1.25 * Math.pow(1.8, i - 60)));
Here's what's wrong: Math.pow(4 * i, 3) is actually (4i)^3 and not 4(i^3). To do the latter, you would need the following:
4 * Math.pow(i, 3)
I'm not entirely sure about the integer division part (you are casting it to double), but you may have to change 5000 / 3 to 5000.0 / 3.
Your problem is inside Math.pow - you're multiplying your index value by a scalar each time.
4 * Math.pow(i, 3)
And
3 * Math.pow(i, 2)
Should fix it.
Edit: And the integer division mentioned in other answers.

Categories

Resources