Diving floats - strange results [duplicate] - 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.

Related

Leibniz Formula using Java

The Leibniz formula for pi is: pi/4 = 1 - 1/3 + 1/5 - 1/7 + 1/9... I am trying to write this in Java but am running into a problem where the output is always 4 (which is not the value of pi). I put my code in a java visualizer and it seems that the problem is that when the code falls into the else statement, it is not subtracting (1-denominator) from pi and that is making the prevPi value and the pi value the same which is causing the do/while loop to end. Does anyone know how I can fix this?
My code:
public static float piCalculatorLeibniz() {
float pi = 0;
int denominator = 1;
float prevPi = 0;
boolean keepGoing = true;
int i = 0;
while (keepGoing == true) {
prevPi = pi;
if (i % 2 == 0) {
pi += (1/denominator);
} else {
pi -= (1/denominator);
}
i++;
denominator += 2;
if (pi == prevPi) {
keepGoing = false;
}
}
pi *= 4;
return pi;
}
You're right. 4 is in fact not the value of Pi.
The problem is that the denominator variable is an int so 1/denomenator is int/int so the result is 0. That makes you exit the loop after just one iteration since pi == prevPi
Just change the denominator type to a double (or float) and you'll get the right answer.
Also, you don't need to write while(keepGoing == true). The variable keepGoing is already a boolean, you can write simply while(keepGoing)
Edit:
I enjoyed playing with this code, so here's a slightly shorter version that's more accurate due to the use of double. It also seems to converge quite a lot faster:
double pi = 0, denominator = 1, prevPi = 1;
while (pi != prevPi) {
prevPi = pi;
pi += (1 / denominator) - (1 / (denominator + 2));
denominator += 4;
}
return pi * 4;
The problem is that integer division results in an integer, not a float or double.
1 / 3 is 0.
To avoid this, you can switch to using a float for the denominator instead of an int.
float denominator = 1.0f;
Make your, all your operands are floating point types. Otherwise your result is an integer.
See Java Language Specifications:
If the promoted type is float or double, then floating-point arithmetic is performed.
Also, on most platforms you can use double without any performance penalty, but this is another topic. ;-)

How do I round up a double to a certain amount of decimals

I want to call a function with a double parameter and an int precision.
This function would have to round that number with the precision number as decimals.
Example: function(1.23432, 4) would have to round that number up with 4 decimals (1.2343). Could anyone help me out with this?
BigDecimal is your friend when it comes to rounding numbers. You can specify a MathContext to explicitly set how you want you rounding to work, and then define the precision you want to use. If you still want a double at the end you can call BigDecimal.doubleValue()
Try this code
String result = String.format("%.2f", 10.0 / 3.0);
// result: "3.33"
First, you get 10precision, then you multiply it by your number, round it to an int and divide by 10precision:
public double round(double number, int precision) {
// 10 to the power of "precision"
double n = Math.pow(10.0, precision);
// multiply by "number" and cast to int (round it to nearest integer value)
int aux = (int) (n * number);
// divide it to get the result
return aux / n;
}
Then you call:
double result = round(1.23432, 4);
System.out.println(result); // 1.2343
Try this:
public String round(double value, int factor) {
double newFactor = convertFactor(factor);
//will convert the factor to a number round() can use
String newVal = Double.toString(Math.round(value / newFactor) * newFactor);
//the value gets rounded
return newVal = newVal.substring(0, Math.min(newVal.length(), factor + 2));
//Convert the result to a string and cut it
//important because a too high value of the factor or value would cause inaccuracies.
//factor + 2 because you convert the double into String, and you have to fill 0.0 out
//Math.min() handles an exception when the factor is higher than the string
}
public double convertFactor(double factor) {
double newFactor = 1;
for(int i = 0; i < factor; i++) {
newFactor /= 10;
//devide the newFactor as many times as the value of the factor isnt reached
}
return newFactor;
}
Use convertFactor() to convert your "normal" factor into a factor (called newFactor) the round() method can use.
The round() method calculates the value and convert it into a String which
the max. lengh of the factor.
Too high values of value and factor would cause inaccuracies, and this little inaccuracies get cutted to get rid of them.
Example code (for your example):
System.out.println("newFactor: " + convertFactor(4)); //only for test!
System.out.println("Rounded value: " + round(1.23432, 4));
//newFactor: 1.0E-4
//Rounded value: 1.2343

Java adding series of fractions together

So, I have a question in my assignment. It's "Add fractions (1/10)+(2/9)+(3/8)+(4/7)+(5/6)+(6/5)+(7/4)+(8/3)+(9/2)+(10/1) together and the output should be 4 decimal points". I've written a loop using 1 and 10 value increasing and decreasing as I go. It doesn't seem to be coming up with the correct answer. It should be 22.218650... etc because I haven't limited the decimal places yet, but it doesn't give the correct answer. The output I'm getting is 18.0.
public class AddThemUp {
// instance variables - replace the example below with your own
public static void main(String [] args) {
int i;
int numer = 1;
int denom = 10;
double addUp = 0.0;
for (i = 1; i <= 10; i++) {
addUp = (numer / denom) + addUp;
numer++;
denom--;
}
System.out.println(addUp);
}
}
The addUp println is just to see if the math is working properly before I try and figure out the decimal place delimiter. Am I using the double improperly or should the numer and denom be double as well? Any help would be appreciated.
You're doing int division which always returns an int -- not the result you want. You need to do double division for this to work. Cast the numerator or denominator of the fraction to double:
((double) numerator / denominator)
Its converting your division (numer/denom) to int so all decimal values in the result are lost. Convert one of the value to decimal e.g. double in your computation e.g. below:
addUp = ((double)numer / denom) + addUp;
You will get your expected result.

Java divison with two integer operands not working?

For some reason my math just returns 0. The value are set, I have checked.
int currentSize = 4079;
int totalSize = 500802;
int percentage = ((currentSize/totalSize) * 100);
progdialog.setProgress(percentage);
Percentage always equals percentage.
Why?
The problem, as other have pointed out, is integer division will turn anything less than 1 to zero. This happens before multiplying by 100. You can change the order of operations to get something better:
int percentage = currentSize * 100 / totalSize;
If you are concerned about rounding, you can use
int percentage = (currentSize * 100 + (totalSize >> 1)) / totalSize;
These avoid the expense of working with double or float values.
you are using 'int's for currentSize and totalSize which results in integer division which removes the fractional part, yielding 0. hence the percentage is always 0.
change it to float percentage = (((float)currentSize/totalSize) * 100); and things will be fine
I assume currentSize and totalSize are int.
currentSize = 4079;
totalSize = 500802;
If they are, then currentSize/totalSize is an integer division. The result will have no fractional part (the fractional part is removed, no round up). Therefore the result is 0.
If one of the operand is double, the result of division will have fraction. Therefore, I cast one integer operand to double.
(double) currentSize
After the calculation, if you want the result to store in int, you have to cast (convert double to int; remove fractional part).
int percentage = (int) ((double) currentSize ...
The whole code is:
int currentSize = 3;
int totalSize = 100;
int percentage = (int) ((double) currentSize / totalSize * 100);
System.out.println(percentage);
If currentSize and totalSize are integers, this calculation will do integer division, which will truncate your fraction down to 0. Use doubles.
Change your code to this:
double percentage = ((double)(currentSize/totalSize) * 100);
progdialog.setProgress(percentage);
Hope it will help yout. :)
Because the result of your calculation is a double with value less than 1. You put it in an integer so it truncates everything behind the decimal separator, resulting in zero. Try storing the value in a double instead.
double occupancyRate = 0.0;
int occupiedRoomsTotal = 12;
int totalRooms = 20;
occupancyRate = (((double) occupiedRoomsTotal / totalRooms)) * 100;
DecimalFormat df2 = new DecimalFormat("#.##");
System.out.println("Occupancy Rate = " + df2.format(occupancyRate) + "%");
Java Division of integers yields zero if both numerator and denominator are both integers and the result is less than 1.
Fix:
Make either of the operands to be floating number or double
e.g. int x = 1;
double y = 3.0;
x/y gives 0.333333
where as 1/3 results in 0.

Why I have to cast this statement in order to get a result?

private final static int L1_MAX_SCORE = 30;
private final static int L2_MAX_SCORE = 150;
public void UpdateLevel(int score) {
double progress;
//returns 0.0
progress = score / (L2_MAX_SCORE - L1_MAX_SCORE) * 100;
//works correctly.
progress = (double) score / (L2_MAX_SCORE - L1_MAX_SCORE) * 100;
Thanks.
Dividing an integer with an integer is defined to do integer division, just like in most (all?) other C-like languages.
By casting score to a double, you are dividing a floating-point value with an integer, and you get a floating-point value back.
Arithmetic operations in Java whose operands are all ints will result in ints, so you're actually assigning an integer result to a double variable. Thus you must cast at least one of them to a double so that the calculations are performed based on doubles, because of the higher precision.
L2_MAX_SCORE - L1_MAX_SCORE = 150 - 30 = 120
Let's assume score is 30
Using floating point, the answer should be 30/120 = 0.4
With integer division, this will get rounded to 0 hence why it 'doesn't work' - it is actually working, but doing the wrong kind of division for your needs
You can either
a) Cast either numerator or denominator as double
b) Rearrange
the formula to be (score * 100) / (L2_MAX_SCORE - L1_MAX_SCORE)
with this, it would become (30 * 100) / 120 = 3000 / 120 = 40
it still does integer division, so if the score is 31 your answer (3100
/ 120) is not 25.8333 but 25

Categories

Resources