How to prevent double from rounding up to two decimal - java

I'm trying to calculate a percentage(9% tax) of a item
double amount = 55.4;
double total = amount * 0.09;
System.out.printf ("%f \n", total);
System.out.printf ("%.2f \n", total);
Returns
4.986000
4.99
How do I make it return 4.98?
Thanks!

Use BigDecimal instead of double.
double is floating point, which cannot accurately represent all fractional amounts, hence the "rounding" problem that you are.experiencing.
BigDecimal is arbitrary-precision, and so doesn't have that problem.

If you want to chop off the thousands place multiple your total by 100 and cast it to an int, then divide it by 100 and cast it to a double:
double amount = 55.4;
double total = amount * 0.09;
int truncated = (int) (total * 100);
double val = truncated * .01;
System.out.printf("%.2f\n", val);
This will give you:
4.98
This can also be done with
double val = Math.floor(total * 100) / 100;
System.out.printf("%.2f\n", val);

Related

Total of percentages is not correct

I am distributing tokens but they are not all distributed. I have multiple percentages and get the amount of tokens to give for that percentage but they do not equal up to the total.
Example:
int tokens = 50;
double[] percentages = new double[] {0.3725, 0.219, 0.115, 0.2935};
int total = 0;
for(double d : percentages){
int amount = (int) (tokens * d);
total += amount;
}
The total is 47 though. I have also tried to round it with Math.round
for(double d : percentages){
double rounded = Math.round(d * 100);
int amount = (int) (tokens * (rounded / 100));
total += amount;
}
The total is 49
I can never seem to get 50, it is always below or above. I want to distribute these tokens are evenly as possible. If you can help please do!!
Use double total. Using int leads to loss of decimal information
double total = 0;
for(double d : percentages){
double amount = (tokens * d);
total += amount;
}
What you should do is round down the percentages as you were originally (casting to int). Then look at how many tokens you have left over. These should be distributed to the cases that are furthest away from their true value.
In each case the error would be:
double error = (percentage * tokens) - (int)(percentage * tokens);
Sort your cases by error, and award the tokens to the cases with the largest error until you have given out all 50.
I'm not sure why this works but I changed the total code to
total += income/1.025;
I think it works because while the loop doesn't display the age for 68 it still runs through one last time. So you'd have to undo the rate for retirement.

Error when adding parenthesis in multiplying int and double in java why?

This is a working code but I am wondering after a full research on multiplying ints and doubles in Java I still can't see why the snippet below the code would give an error. Any help please?
public class Arithmetic {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
double mealCost = scan.nextDouble(); // original meal price
int tipPercent = scan.nextInt(); // tip percentage
int taxPercent = scan.nextInt(); // tax percentage
scan.close();
// Calculate Tax and Tip:
double tip = mealCost * tipPercent / 100; //HERE IS MY PROBLEM
double tax = mealCost * taxPercent / 100; //HERE IS MY PROBLEM
// cast the result of the rounding operation to an int and save it as totalCost
int totalCost = (int) Math.round(mealCost + tax + tip);
System.out.println("The total meal cost is " + totalCost + " dollars.");
}
}
Knowing that this answer is more logical and gives a different value than the one above?!
double tip = meal * (tipPercent/100);
double tax = meal * (taxPercent/100);
In your 1st example, the multiplication is performed first, resulting in a double number that is then divided by 100, giving the correct double result:
mealCost * tipPercent / 100;
In your 2nd version, an integer division is performed first, resulting in an integer result. Assuming that tipPercent less than 100, the result will be zero.
If you like the second version better, just use a floating point constant:
double tip = meal * (tipPercent/100.0);
Let's imagine:
int tipPercent = 10;
double mealCost = 100.123d;
And
double tip = mealCost * tipPercent / 100;
1. 100.123(double) * 10(int) = 1001.23(double)
2. 1001.23(double) / 100(int) = 10.0123(double)
In the second:
double tip = mealCost * (tipPercent / 100);
10(int) / 100(int) = 0(int)
100.123(double) * 0 = 0(double)

Method not dividing for desired double value

In my program, I'm trying to divide two double values and return the quotient of it. Like this:
public double getMonthlyPayment(){
double monthlyRate = AnnualInterestRate / 1200;
double numberOfMonths = numberOfYears * 12;
double dividend = (loanAmount * monthlyRate);
double divisor = (1 - Math.pow(1+monthlyRate, -numberOfMonths));
return dividend / divisor;
}
Currently it's not returning the value I'm expecting. It's only returning the dividend value and not the value when dividend is divided by divisor.
For example, since this is a loan calculator, I need a loan of $2000 with 5% interest for 2 years. In order to achieve this value, you would need to use a certain equation.
I've made my own form of that equation in the code above and it's only returning the dividend value, which is (loanAmount * monthlyRate), instead of returning dividend value divided by (1 - Math.pow(1+monthlyRate, -numberOfMonths))
Could someone help me with this?
Thanks in advance for any help.
Your code doesn't show, but if AnnualInterestRate is an int, then the division by 1200 is done using integer logic, and the result (an integer) is then coerced to double. Specifying 1200.0 will force coercion of AnnualInterestRate to double before the division.
We do not know data types of all variables in your question. If the data type of right side is integer and left side is double, explicitly cast the result to double
Correct code should be:
public double getMonthlyPayment(){
double monthlyRate = (double)AnnualInterestRate / 1200;
double numberOfMonths = (double) numberOfYears * 12;
double dividend = (loanAmount * monthlyRate);// Assuming loanAmount is double
double divisor = (1 - Math.pow(1+monthlyRate, -numberOfMonths));
return dividend / divisor;
}

How do I format double input in Java WITHOUT rounding it?

I have read this question Round a double to 2 decimal places It shows how to round number. What I want is just simple formatting, printing only two decimal places.
What I have and what I tried:
double res = 24.695999999999998;
DecimalFormat df = new DecimalFormat("####0.00");
System.out.println("Value: " + df.format(res)); //prints 24.70 and I want 24.69
System.out.println("Total: " + String.format( "%.2f", res )); //prints 24.70
So when I have 24.695999999999998 I want to format it as 24.69
You need to take the floor of the double value first - then format it.
Math.floor(double)
Returns the largest (closest to positive infinity) double value that is less than or equal to the argument and is equal to a mathematical integer.
So use something like:
double v = Math.floor(res * 100) / 100.0;
Other alternatives include using BigDecimal.
public void test() {
double d = 0.29;
System.out.println("d=" + d);
System.out.println("floor(d*100)/100=" + Math.floor(d * 100) / 100);
System.out.println("BigDecimal d=" + BigDecimal.valueOf(d).movePointRight(2).round(MathContext.UNLIMITED).movePointLeft(2));
}
prints
d=0.29
floor(d*100)/100=0.28
BigDecimal d=0.29
Multiply the number by 100 and cast it to an integer. This cuts off all the decimal spaces except the two you want. Divide the result by 100.00. (24.69).
int temp = (int)(res * 100);
double result = temp / 100.00;
or the same thing in one line of code:
double result = ((int)(res * 100)) / 100.00;
In addition to using Math.floor(double) and calculating a scale (e.g. * 100 and then / 100.0 for two decimal points) you could use BigDecimal, then you can invoke setScale(int, int) like
double res = 24.695999999999998;
BigDecimal bd = BigDecimal.valueOf(res);
bd = bd.setScale(2, RoundingMode.DOWN);
System.out.println("Value: " + bd);
Which will also give you (the requested)
Value: 24.69

Raising a number to a power in Java

Here is my code. For some reason my BMI is not calculated correctly.
When I check the output on a calculator for this : (10/((10/100)^2))) I get 1000, but in my program, I get 5. I'm not sure what I am doing wrong. Here is my code:
import javax.swing.*;
public class BMI {
public static void main(String args[]) {
int height;
int weight;
String getweight;
getweight = JOptionPane.showInputDialog(null, "Please enter your weight in Kilograms");
String getheight;
getheight = JOptionPane.showInputDialog(null, "Please enter your height in Centimeters");
weight = Integer.parseInt(getweight);
height = Integer.parseInt(getheight);
double bmi;
bmi = (weight/((height/100)^2));
JOptionPane.showMessageDialog(null, "Your BMI is: " + bmi);
}
}
^ in java does not mean to raise to a power. It means XOR.
You can use java's Math.pow()
And you might want to consider using double instead of int—that is:
double height;
double weight;
Note that 199/100 evaluates to 1.
we can use
Math.pow(2, 4);
this mean 2 to the power 4 (2^4)
answer = 16
^ is not the operator you want. You are looking for the pow method of java.lang.Math.
You can use Math.pow(value, power).
Example:
Math.pow(23, 5); // 23 to the fifth power
Your calculation is likely the culprit. Try using:
bmi = weight / Math.pow(height / 100.0, 2.0);
Because both height and 100 are integers, you were likely getting the wrong answer when dividing. However, 100.0 is a double. I suggest you make weight a double as well. Also, the ^ operator is not for powers. Use the Math.pow() method instead.
Too late for the OP of course, but still...
Rearranging the expression as:
int bmi = (10000 * weight) / (height * height)
Eliminates all the floating point, and converts a division by a constant to a multiplication, which should execute faster. Integer precision is probably adequate for this application, but if it is not then:
double bmi = (10000.0 * weight) / (height * height)
would still be an improvement.
You should use below method-
Math.pow(double a, double b)
From (https://docs.oracle.com/javase/8/docs/api/java/lang/Math.html#pow-double-double-)
Returns the value of the first argument raised to the power of the second argument.
int weight=10;
int height=10;
double bmi;
bmi = weight / Math.pow(height / 100.0, 2.0);
System.out.println("bmi"+(bmi));
double result = bmi * 100;
result = Math.round(result);
result = result / 100;
System.out.println("result"+result);
1) We usually do not use int data types to height, weight, distance,
temperature etc.(variables which can have decimal points)
Therefore height, weight should be double or float.
but double is more accurate than float when you have more decimal points
2) And instead of ^, you can change that calculation as below using Math.pow()
bmi = (weight/(Math.pow(height/100, 2)));
3) Math.pow() method has below definition
Math.pow(double var_1, double var_2);
Example:
i) Math.pow(8, 2) is produced 64 (8 to the power 2)
ii) Math.pow(8.2, 2.1) is produced 82.986813689753 (8.2 to the power 2.1)
I did the benchmarking with Math.pow(x,2) and x*x,
the result is that Math.pow() is easily forty times slower than manually multiplying it by itself, so i don't recommend it for anything where a little bit of performance is required.
Here's the results:
proof_of_work: 19.284756867003345
time for Math.pow(x,2) in ns: 35143
proof_of_work: 19.284756867003345
time for x*x in ns: 884
manual calculation is 39 times faster
and here's the test-code
double r1 = 4.391441320;
long multiply_d1 = System.nanoTime();
double multiply_dr = Math.pow(r1,2);
long multiply_d2 = System.nanoTime();
System.out.println(("proof_of_work: ") + (multiply_dr));
System.out.println(("time for Math.pow(x,2) in ns: ") + (multiply_d2 - multiply_d1));
long multiply_t1 = System.nanoTime();
double multiply_tr = r1*r1;
long multiply_t2 = System.nanoTime();
System.out.println(("proof_of_work: ") + (multiply_tr));
System.out.println(("time for x*x in ns: ") + (multiply_t2 - multiply_t1));
System.out.println(("manual calculation is ") + ((multiply_d2 - multiply_d1) / (multiply_t2 - multiply_t1)) + (" times faster"));
Most efficient solution is
public Float fastPow(Float number, Integer power) {
if (power == 0) {
return 1.0f;
} else if (power % 2 == 1) {
return fastPow(number, power - 1) * number;
} else {
return fastPow(number * number, power / 2);
}
}
Let A is our number and N our power. Then A^2^N = (A^2)^N. And A^N = (A^2)^N/2. The function above reflects this relationship.

Categories