Java - Else If loop will NOT work with instance variable - java

I'm attempting to calculate how much tax a user should pay, based on wage. For example, calculating 20% in the first if loop, this will be saved in generaltax:
int generalTax = 0;
int userGrossPay = 50000;
if (userGrossPay <= 10600) {generalTax += 0;}
else if (((userGrossPay >= 10600) && (userGrossPay <= 31785))) { generalTax = ((20/100) * userGrossPay); }
else if (((userGrossPay >= 31786) && (userGrossPay <= 150000))) { generalTax = ((40/100) * userGrossPay); System.out.println(generalTax);}
else if (userGrossPay > 150001) {generalTax = ((45/100) * userGrossPay); }
else{System.out.println("error");};
userGrossPay -= generalTax;
System.out.println(userGrossPay);
However generalTax pay is for some reason always stuck as 0 and is not properly updating on each iteration.

Your problem is that you are always adding 0 or assigning 0 to generalTax.
For example, (20/100) * userGrossPay is 0, since 20/100 is 0 due to int division. Change it too 0.2 * userGrossPay or 20.0/100 * userGrossPay. Similarly change all other places where you divide two integers.

This is caused by integer division.
If you mix floating data type with integer, it will give you a data conversion by promotion.
For example:
int num = 5;
System.out.println(num / 2); //Gives you 2
System.out.println(num / 2.0); //Gives you 2.5
System.out.println(num * 2); //Gives you 10
System.out.println(num * 2.0); //Gives you 10.0
System.out.println(num + 2.5); //Gives you 7.5
If all operands in the operation are integers, your output will be integer as well. This is how you got into an integer division accidentally.
((20/100) * userGrossPay);
I see that you already accepted Eran's answer and understood what went wrong, I am here to give you some additional information.

Related

I need help making change in java. It doesnt give out change correctly

Hi I'm trying to make a method that gives you change in Hundreds, Fifties, Twenties, Tens, Fives, ones as well as quarters dimes and nickels. the user gives input and its supposed to look something like this: 6.87 1 five 1 one 3 quarters 1 dime 2 pennies
So far I have this as my code:
import java.util.Scanner;
/**
*
* #author Cjespinomartine
*/
public class Assignment04 {
public static void main(String[]args) {
Scanner stdin = new Scanner(System.in);
System.out.println("Enter your amount");
double amount = stdin.nextDouble();
double remainder = Math.round(amount * 100);
double hundreds = remainder / 1000;
remainder = remainder / 1000;
double fifties = remainder / 500;
remainder = remainder / 500;
double twenties = remainder / 200;
remainder = remainder % 200;
/*
double fives = remainder / 5;
remainder = remainder % 5;
double ones = remainder / 1;
remainder = remainder % 1;
double quarters = remainder / .25;
remainder = remainder % .25;
double dimes = remainder / .10;
remainder = remainder %10;
double nickels = remainder / .5;
remainder = remainder % .5;
double pennies = remainder;
*/
System.out.println(hundreds + "hundred/s");
System.out.println(fifties + "fiftie/s");
System.out.println(twenties + "twentie/s");
/* System.out.println(fives + "five/s");
System.out.println(ones + "one/s");
System.out.println(quarters + "quarter/s");
System.out.println(dimes + "dime/s");
System.out.println(nickels + "nickel/s");
System.out.println(pennies + "cent/s");
*/
}
}
It doesn't give out change in order it just gives out hundreds. I commented some of the change because I'm trying to get the math right. I think the assignment required if and else if so if it does can you help me out with where I put it. any help will mean a lot i'm very stuck thank you.
There are a few things wrong.
The first issue is your initial handling of remainder – you're multiplying by 100, so if input is 1274.56, you end up with 127456 (ignoring floating point problems which are valid but I'll stay focused on this first point). The output of Math.round() is either an int or long, but definitely not a double so you're adding confusion for yourself by storing it as a double – instead, store the result as long. From there, when you calculate hundreds, you need to divide by 10,000 not 1,000. Also, store that as an int, not a double. Here's what that would look like:
long remainder = Math.round(1274.56 * 100);
int hundreds = (int) remainder / 10000;
System.out.println("hundreds: " + hundreds);
The above prints out "12" for hundreds, which is what you want.
The second issue is how you're calculating remainder. You want everything that's "left over" from the prior calculation which you do by using % (modulus operator), and also use 10,000 instead of 1,000. For the hundreds case, it would be this:
remainder = remainder % 10000;
System.out.println("remainder: " + remainder);
The above code would print this:
remainder: 7456
This should give you enough to get the rest of your math working properly.
remainder = remainder / 1000; is wrong. What you want is the remainder after you've taken out all the hundreds. remainder = remainder % 1000; -looks like the commented out ones are correct...
Also don't use floating point types for money. Google will give you a thousand reasons why.

Two values won't produce quotients they should [duplicate]

This question already has answers here:
Division of integers in Java [duplicate]
(7 answers)
Closed 6 years ago.
I'm currently doing an assignment for school, and I need to create a program that uses Math.random() to get a random value, and depending on the value, output "Heads" or "Tails". It needs to do this 10 times. Then, it needs to find the percentage of times that the program output heads, and how many it output tails. However, it isn't working correctly. It always outputs that heads/tails were 0% of the tosses. Can someone please explain why?
public class HeadsTails
{
public static void main(String[] args)
{
int v;
double i;
int heads = 0, tails = 0;
double headsPercent, tailsPercent;
for(v = 1; v <= 10; ++v)
{
i = Math.random();
if(i <= 0.5)
{
System.out.println("Heads");
heads = heads + 1;
}
else if(i > 0.5)
{
System.out.println("Tails");
tails = tails + 1;
}
}
headsPercent = (heads / 10) * 100;
tailsPercent = (tails / 10) * 100;
System.out.println("Heads were " + headsPercent + "% of the tosses.");
System.out.println("Tails were " + tailsPercent + "% of the tosses.");
}
}
I am also quite open to any improvements that can be made, besides those that just make the program function properly.
The problem is integer math. heads and tails are both int, so:
heads / 10
...yields an int result, which will almost always be 0 in your case because in int-land, 1 / 10, 2 / 10, through 9 / 10 are all 0. The only time you'd get anything else would be if all the rolls were heads or all were tails, where 10 / 10 is 1.
Cast to double before doing the math:
headsPercent = ((double)heads / 10) * 100;
tailsPercent = ((double)tails / 10) * 100;
Doing that fixes the problem.
Side note 1: You can add to a variable using +=, e.g.:
heads += x;
And of course, when what you're adding is 1, you can just use the increment operators, either prefix:
++heads;
or postfix
heads++;
(In terms of updating heads and tails, it doesn't matter which.)
Side note 2: You don't need else if (i > 0.5). If you think about the logic, you have if (i <= 0.5) ... else ... That means that i will definitely be > 0.5 once you get to the else, no need for the if (i > 0.5) part.
And if you do that, you don't even need i anymore:
for(v = 1; v <= 10; ++v)
{
if(Math.random() <= 0.5)
{
System.out.println("Heads");
++heads;
}
else
{
System.out.println("Tails");
++tails;
}
}

Sum the first N numbers in java

Hello, I am new to programming and I am trying to write a small program where it will calculate the sum for first N numbers. The problem is it does not work for even numbers. I have not managed to figure out why.
My code is as follow:
int n = Integer.parseInt(args[0]);
int sum = (1+n)/2*n;
System.out.println(sum + " is the sum of first " + n + " numbers");
It doesn't work for even n because (n+1)/2 is truncated to an int.
This means that if, for example, n=4, (n+1)/2 results in 2 instead of 2.5, so when you multiply it by n, you get 8 instead of the desired 10.
You can overcome this problem simply by changing the order of the operations. If you first multiply n by (n+1), the result is guaranteed to be even, so dividing it by 2 will produce the correct answer.
int sum = n*(1+n)/2;
You have integer division with (1+n)/2. If your number is even, then (1+n) is odd and the division by 2 will truncate any decimal result, so that an int divided by an int is still an int.
Multiply by n first, then divide by 2. This ensures that the product is even before dividing, so the result is correct.
int sum = (1+n) * n / 2;
One can use ((n * (n + 1)) / 2). But I think the following will work without overflow errors for a few additional values of n:
if ((n & 1) == 0) {
sum = ((n >> 1) * (n + 1));
} else {
sum = (n * ((n + 1) >> 1));
}

Java: round to nearest multiple of 5 (either up or down)

I need to round a number to nearest multiple of 5 (either up or down). For example, here are the list of numbers and the number next to it that it needs to round up/down to.
12.5 10
62.1 60
68.3 70
74.5 75
80.7 80
Numbers will only be positive.
haven't tested it, but 5*(Math.round(f/5)); should work
Nearest Multiple of 5
for Upper value
5*(Math.ceil(Math.abs(number/5)));
for Lower Value
5*(Math.floor(Math.abs(number/5)));
it gives Positive value only.
public static void main(String args[]) {
double num = 67.5;
if (num % 5 == 0)
System.out.println("OK");
else if (num % 5 < 2.5)
num = num - num % 5;
else
num = num + (5 - num % 5);
System.out.println(num);
}
Try this.
How about something like this:
return round((number/5))*5;
Gefei's solution is working, but I had to convert explicitly to double like this: 5*(Math.round((double)f/5))
There are many other solutions on this page, but I believe this is the most concise one.
To find the closest multiple of x for a given number,
let x be the multiple and num be the given number:
// The closest multiple of x <= num
int multipleOfX = x * ( num / x );
In your case:
int multipleOf5 = 5 * ( num / 5 );
In case you have an integer as input, otherwise the accepted answer will round it to down.
int value = 37;
value = (int) ( Math.round( value / 5.0 ) * 5.0 );

Java: Generating a random numbers with a logarithmic distribution

I am attempting to generate a random numbers with a logarithmic distribution.
Where n=1 occurs half of the time, n=2 occurs a quarter of the time, n=3 occurs an eighth of the time, etc.
int maxN = 5;
int t = 1 << (maxN); // 2^maxN
int n = maxN -
((int) (Math.log((Math.random() * t))
/ Math.log(2))); // maxN - log2(1..maxN)
System.out.println("n=" + n);
Most of the time, I am getting the result I need, however once every so often, I get a value of n that is larger than maxN.
Why is this so? The way I see it, the max value of Math.random() is 1.0;
therefore the max value of (Math.random() * t)) is t;
therefore the max value of log2(t) is maxN, since t = 2^maxN;
Where has my logic gone off track?
Thanks
logarithm of numbers less than 1.0 is negative. When the random number generated is such that it is less than 1.0, the expression ((int) (Math.log(Math.random() * t) / Math.log(2))) is a negative number and hence maxN - (the negative number) is more than maxN.
The following expression should give correct distribution.
n = Math.floor(Math.log((Math.random() * t) + 1)/Math.log(2))
Note that:
0.0 <= Math.random() <= 1.0
0.0 <= Math.random() * t <= t
1.0 <= (Math.random() * t) + 1 <= t + 1.0
0.0 <= Math.log((Math.random() * t) + 1) <= Math.log(t + 1.0)
0.0 <= Math.log((Math.random() * t) + 1)/Math.log(2) <= Math.log(t + 1.0)/Math.log(2)
Since t = 2^maxN,
Math.log(t + 1.0)/Math.log(2) is slightly larger than maxN.
So do a Math.floor and you get the correct result:
0.0 <= Math.floor(Math.log((Math.random() * t) + 1)/Math.log(2)) <= maxN
If Math.random()*t is less that 1, then you will get a negative answer when you take Math.log(Math.random()*t), by the rules of Logarithms. This means that you will get a negative answer when you divide by Math.log(2) because that is 0.69314718055994530941723212145818. This is a negative number divided by a positive number. The answer is negative. maxN - a negative number = maxN + something positive, so n is greater than maxN. To fix this cast Math.random()*t to an int and add 1:
int n = maxN -
((int) (Math.log((int)((Math.random() * t)+1))
/ Math.log(2))); // maxN - log2(1..maxN)
Notice the cast inside the log, and the add of 1.
The purpose of adding one would be to avoid the 0. Can't take a log of 0. Also, without adding 1, you could never get maxN inside the log, because Math.random() never produces 1. This way, instead of getting 1 half, 2, a fourth, 3, and eighth, it just starts at 0. This gives 0, a half, 1 a fourth, 2 an eighth, etc.
The problem is in the other end of the scale.
Consider what would happen if you get a very small random number.

Categories