The following code with presence and absence of parentheses produce different output. Why?
System.out.println((double) 3/6); // output 0.5
System.out.println((double) (3/6)); // output 0.0
Because in the first example you are actually doing ((double) 3)/6, and therefore the result is a double too.
In the second one, you are performing an integer division, and then you are casting the result. 3/6 = 0, and (double) 0 = 0.0.
In the first example, you are casting 3 to a double before dividing by an int. According the Java type conversion rules, the output is a double(0.5 in this case).
In the second example, you are dividing an int by an int. Since the number you are dividing is smaller than the number you are dividing with, the answer is zero. Then you are simply casting int 0 to double 0.
Related
Working on a Java class, its making me crazy because this expression is evaluating to zero, I need it to evaluate to a double, then round it down to the nearest int. So what Im trying to get is for days to be a whole number of days, yet when I run it through java it evaluates to 0. When I run it through my calculator it evaluates to the correct value. I would love a fix and an explanation to why this what I already have isn't working.
public int getEventDays(){
//variables
double daysCalc;
int days;
//logic
if (getStatus().equals("filling")){
//this is indented less to fit everything on one line, its not this way in
//the fractions are for unit conversion
daysCalc= Math.floor(((capacity-storage)/(inflow-outflow))*(43560)*(1/3600)*(1/24));
days = (int)daysCalc;
}
else if (getStatus().equals("emptying")){
//this is indented less to fit everything
//the fractions are for unit conversion
daysCalc=Math.floor(((storage-0)/(outflow-inflow))*(43560)*(1/3600)*(1/24));
days = (int)daysCalc;
}
else{
days = -1;
}
return days;
}
Change your code to this :
daysCalc = Math.floor(((storage-0)/(outflow-inflow))*(43560)*(1.0/3600)*(1.0/24));
Explanation:
The right hand expression is returning an integer value. In your case, 1/3600 is rounded to 0, similar to the case of 1/24.
Now by using 1.0 instead of 1, it is giving the unrounded float value of 1/3600.
Your problem is connected with the order of operations within your expression. The parentheses around 1/3600 and 1/24 cause these expressions to be evaluated first - and since each of these divisions has an expression of integer type on either side of the division, it's treated as an integer division. In other words, 1/3600 and 1/24 are both evaluated as integers, to give a result of zero. This means that your arithmetic includes a couple of multiplications by zero, which is why your result is zero.
The simplest fix is to understand that multiplying by the reciprocal of some number is the same as dividing by that number. In other words, you could simplify the calculation to
daysCalc = Math.floor( storage / ( outflow - inflow ) * 43560 / 3600 / 24 );
which will give the correct result, provided storage, outflow and inflow are not all integers.
On the other hand, if storage, outflow and inflow are all integers, then you'll need to make sure that the first division is also not treated as an integer division. You could do this by writing
daysCalc = Math.floor((double) storage / ( outflow - inflow ) * 43560 / 3600 / 24 );
which forces the division to be done with floating point arithmetic; and thereafter, each one of the divisions is done in floating point.
I just wanted to calculate the VAT, but when i divide by 100 to obtain the total price (price*VAT/100), but it returns me 0.0. Here's my code:
a.price=sc.nextInt();
a.vat=sc.nextInt();
a.total=a.precio*a.iva/100;
'total' is defines as FLOAT instead of INT
You need to cast the expression to float. I used a float literal here 100.0f.
a.total= a.precio*a.iva/100.0f;
Welcome to integer arithmetic. You want to do this with a float or double value, and quite likely you should be using BigDecimal to maintain precision.
Be careful with "/ 100" operation in Java which can lead you to miscalculations and is an expensive operation (think that the / operation is done in the binary system and not in the decimal system).
I was in a bank project where all the amounts were with two decimals in long values (for example 123.45€ were 12345), so we had to do the same operation as you ("/ 100"). We found that some amounts lead to round calculations... missing a cent (which in banking is unacceptable).
However BigDecimal handles the same operation with a simple "movePointLeft", so I recommend you to use the next code:
total = (BigDecimal.valueOf(price * VAT)).moveLeft(2).doubleValue()
You have to cast your integers, otherwise your result will be computed as an integer before being assigned to a.total. Something like:
a.total = (float)(a.precio) * (float)(a.iva) / 100;
At least on of division operands must be float or double so the result is double. Otherwise the division result is integer.
a.total=a.precio*a.iva/100.0
or if you really need float, you can skip some precision
a.total=(float)(a.precio*a.iva/100.0)
The problem is that what you're putting in your float variable is the result of operations on integers: it's an integer. In other words, a.precio * a.iva / 100 is first evaluated to an integer (that's where you lose precision), and then this integer is assigned to a.total as a float.
You therefore need to specify that the operation a.precio * a.iva / 100 has to be done on floats by casting the integer values.
Change
a.total=a.precio*a.iva/100;
to
a.total= ((float)a.precio)*a.iva/100;
I have the following code:
int i = (int) 0.72;
System.out.println(i);
Which yields the following output:
0
I would of imagined that the variable i should have the value of 1 (since 0.72 > 0.5 => 1), why is this not the case?
(I imagine that when casting to int, it simply cuts of the decimal digits after the comma, not taking into account of rounding up; so I'll probably have to take care of that myself?)
Correct, casting to an int will just truncate the number. You can do something like this to get the result you are after:
int i = (int)Math.round(0.72);
System.out.println(i);
This will print 1 for 0.72 and 0 for 0.28 for example.
Because when you cast a double to int, decimal part is truncated
UPDATE Math.round will give your desired output instead of Math.ceil:
System.out.println(Math.round(0.72));
// will output 1
System.out.println(Math.round(0.20));
// will output 0
You can use Math.ceil :
System.out.println(Math.ceil(0.72));
// will output 1
System.out.println(Math.ceil(0.20));
// will output 1
Casting to an int implicity drops the decimal part. That's why you get 0 because anything after the 0 is removed (in your case the 72). If you want to round then look at Math.round(...)
Explicit cast does a conversion a float/double value to an int variable (which discards the fractional part)
Java does not round-off the number like we do.It simply truncates the decimal part.
If you want to round-off the number use java.lang.Math
Casting double to int truncates the non-integer portion of the number.
To round numbers as you describe, use Math.round()
As a complete Java beginner, and just in case my experience is useful to someone, I was just making the following mistake:
int x = (int) Math.random() * 10;
... which will always set x to 0. Instead, I should've done int x = (int) (Math.random() * 10);.
Not much of a Java-know-how specific mistake, but I'll just throw this in case anyone puzzled by this stumbles upon this question.
I am trying to get percentage but the result is error, i have expression as:
Uper=(Upcount/total)*100;
where Uper is float while Upcount and total is integer i am getting the result Uper=0.
An int divided by an int will result in an int. That could be 0. Multiply 0 * 100, convert to float, and the result is still 0.0. You need at least one of the operands to be floating point before the division will give a floating point result.
Try:
Uper = ((float)Upcount/(float)total)*100.0;
The extra (float) is me being paranoid that this line might be modified in the future without fully understanding the floating-point requirement. The 100.0 is to be explicit about what you want -- a floating point result.
Perhaps changing Upcount or total to float would make more sense.
the division of 2 integers will always result in an integer which is 0 in your case.
To solve this, use the following code:
Uper = ((Double) Upcount) / total * 100
Casting at least 1 member to Double or Float will get the result you want
I have a problem with dividing a long value by 1000 and round it to an integer.
My long value is: 1313179440000
My code is
long modificationtime = 1313179440000;
Math.round(modificationtime/1000l)
If i print out the divided and formated value, it returns me:
1313179392
so.
value : 1313179440000
expected: 1313179440
got : 1313179392
I do not know why this happens.
Can anybody help me?
best regards,
prdatur
Math.round(float) is being used. A float has a larger range than a long, but it cannot represent all integers within that range -- in this case the integer 1313179440 (the original result of the division) lies in the part of the range that exceeds integer precision.
Don't use Math.round as it's not needed (input is already an integer!), or;
Use Math.round(double), as in: Math.round(modificationTime/1000d). Note that the divisor is a double and thus the dividend (and the result) of the expression are also promoted to double.
Happy coding.
The reason you get that result is that Math.Round() accepts either a double. Since your number isn't exactly representable as a double, the closest number that is gets passed in.
Note that round() is completely unnecessary here. modificationTime/1000l requires no rounding. If you do require rounding, change the argument to modificationTime/1000d.