The precendence of operators in Java is not applied - java

I have this piece of code and according to this page here
The below output should by right give me, 98.24 but this is giving me 68.8, what is that I am missing here?
public class Qn1
{
public static void main(String[] args)
{
double cel = 36.8;
double fah = ((9 / 5 )* cel) + 32;
System.out.println(cel + "deg C =" + fah +" deg F");
}
}

Use 9.0 / 5 instead of 9 / 5 in bracket.
9 / 5 is integer division and its value is 1. And hence the result. You just need to make one of the numerator or denominator a double / float value to enforce floating-point division.
((9 / 5 ) * cel) + 32 = (1 * 36.8) + 32 = 68.8
And what you need is: -
((9.0 / 5 ) * cel) + 32 = (1.8 * 36.8) + 32 = 66.24 + 32 = 98.24

double fah = ((9.0 / 5 )* cel) + 32;

The problem is you are not using double but int. Use
double fah = ((9d / 5d) * cel) + 32d;

Use at least one double operand:
double fah = 9.0 / 5 * cel + 32;
double fah = 9 / 5.0 * cel + 32;
double fah = 9.0 / 5.0 * cel + 32;
These three ways are valid and note that parenthesis are unnecessary.

9 is integer, so is 5 : so 9/5 is using integer division, meaning it results into 1 (integer) and not 1.8 (float)
1*36.8 +32 = 68.8

9 / 5 in integer arithmetic is 1

Related

what is Double here? [duplicate]

This question already has answers here:
Int division: Why is the result of 1/3 == 0?
(19 answers)
Closed 1 year ago.
I understand double as a variable type but in line 4 it might be used as datatype conversion. I just don't get the double used in line 6, am I completely missing the point here?
public static void main(String args[]) {
int discountPercentage = 10;
double totalPrice = 800;
double priceAfterDiscount = totalPrice * (1 - ((double) discountPercentage / 100));
if (totalPrice > 500) {
priceAfterDiscount = priceAfterDiscount * (1 - ((double) 5 / 100));
}
System.out.println("Customer has paid a bill of amount: "+ priceAfterDiscount);
}
Writing 5 / 100 is an int division as both operand are ints, and in Java that will result in 0.
See Int division: Why is the result of 1/3 == 0?
To get 0.05, you need to make a division with double
define an operand as double explicitly
5.0 / 100
5 / 100.0
cast an operand
(double) 5 / 100
5 / (double) 100

Float vs double Math Java

Is there a precision difference between the following (assuming the value of a and b can be represented without loss of precision in a float).
With floats:
float a;
float b;
double result = 1 + a*b;
With doubles:
double a;
double b;
double result = 1 + a*b;
Simple example:
float a = 16777217; // Largest int exactly representable in a float.
float b = 16777217;
System.out.println((double)(1 + a*b));
double c = 16777217;
double d = 16777217;
System.out.println(1 + c*d);
Output (Ideone):
2.81474976710656E14
2.8147501026509E14
So yes, there is a loss of precision using float.
There is a loss of precision in
float a;
float b;
double result = 1 + a*b;
the float representation.
the product of a and b which will also be a float. Note: a * b is a float
the addition on 1 could result in a loss of precision.
To should that a * b can lose more precision
for (int i = 1; i < 100; i += 2) {
float a = i;
float b = 1.0f / i;
if ((double) a * b != a * b && a * b != 1)
System.out.println(i + " " + (double) a * b + " " + a * b);
}
prints
41 0.999999962747097 0.99999994
47 0.9999999683350325 0.99999994
55 0.9999999683350325 0.99999994
61 0.9999999441206455 0.99999994
83 0.999999962747097 0.99999994
97 0.999999969266355 0.99999994
note: it could also happen recover precision lost and get the right answer after b has lost precision
for (int i = 1; i < 20; i += 2) {
float a = i;
float b = 1.0f / i;
if (b != 1.0 / i && a * b == 1)
System.out.println(i + " " + (double) a * b + " " + a * b);
}
prints
3 1.0000000298023224 1.0
5 1.0000000149011612 1.0
7 1.0000000447034836 1.0
9 1.0000000074505806 1.0
11 1.0000000298023224 1.0
13 1.000000037252903 1.0
15 1.0000000521540642 1.0
17 1.0000000037252903 1.0
19 1.0000000074505806 1.0
There can be a loss of precision difference in a*b part when you evaluating it as floats and doubles. So yes, with some values, 2nd one will be more accurate.

What is wrong with arithmetic operation

I know perhaps is stupid question but I don 't understand what is wrong in the following operation:
value = 8.14
double netvalue = value / (1 + 23 / 100);
and the result is:
netvalue = 8.14
Division has precedence over addition, so
1 + 23 / 100 is evaluated as 1 + (23/100) which is 1 + 0 (23/100 is 0 since it is int division, so the result is an int), so you are dividing value by 1.
You can change 23 to 23.0 to achieve floating point division :
double netvalue = value / (1 + 23.0 / 100);
Or you can simply divide by 1.23 :
double netvalue = value / 1.23;
Let understand this
double netvalue = value / (1 + 23 / 100);
the first thing evaluated is 23/100 gives 0
and 1+ 0 = 1
and finally double netvalue = 8.14/1; gives 8.14

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

Compute average of two double?

I am trying compute average of two double value, but it dose not work truly. I think it is "rounding error" am I right? and how can I fix it?
point.get(0)=1
point.get(1)=4
double Average = (double)(point.get(0) + point.get(1) / 2);
Output:
Average: 3.0
Why?
double Average = (double)(point.get(0) + point.get(1) / 2);
is executed as
Average = (double)(1 + 4/2) = (double) (1+2) = 3.0
Problem
Divison(/) has higher precedence than addition(+)
Fix
You need to add brackets for proper calculation:
double Average = (double)((point.get(0) + point.get(1)) / 2);
should execute as:
Average = (double)((1 + 4)/2) = (double) (5/2) = 2.5
double Average = (double)(point.get(0) + point.get(1) / 2)
Operator precedence trouble. Try this:
double Average = (point.get(0) + point.get(1)) / 2.0;
This has to do with the order of operators - the / has a higher precedence than +, so you are actually getting 1 + (4/2) which does equal 3.
Try this instead:
double Average = (double)((point.get(0) + point.get(1)) / 2);
The extra brackets will correct your issue.
Division takes precedence over addition. Hence,
Average = (double)(1 + 4/2) = (double) (1+2) = 3.0
You should probably make it more like
Average = (double)((1+4)/2)

Categories