Ok so basic question here.
double test = 1/3 * 3.14;
I realize that you need to do (1.0/3) in order to get the actual double number. But what I am wondering is why. I would have thought that since you are multiplying by 3.14 this would make it a double.
So am I correct in thinking that whenever two values are used in an arithmetic equation, regardless of what is happening around them, if they are integers then you will get an integer value?
ie. x/y * z
while x is divided by y that is all that the programme cares about and if they are both integers you will get an integer value back? It is only when you multiply it by z (3.14) that it becomes a double.
Evaluation occurs from left to right when two operators have equal precedence. * and / have equal precedence.
1 / 3 * 3.14 evaluates 1 / 3 first. Both operands are int, the first operation is integer division, and the result is an int.
Next, result * 3.14 is evaluated. One operand is an int, the other operand is a double, and we have mixed types. Java does us a favor and casts the int to a double to preserve accuracy. Floating point division occurs, and the result is a double.
With operators of equal precedence, the associativity takes over. These operators / and * are left-associative, which means that the order of operations proceeds from left to right.
So, 1/3 happens first, and integer division happens before the 3.14 has a chance to promote them to doubles.
Because according to the rules of arithmetics, 1/3 is calculated first. Since it's 2 integers, it's an integer division, resulting in 0. Afterwards you have a double calculation, but the error has already happened.
My understanding is that this has to do with autoboxing in java. Java assumed that the 1/3 is dividing two ints so you'd get an int back (casted into a double).
If you did 1/3D, you'd get 0.33333333 back
Related
For example,
int result;
result = 125/100;
or
result = 43/100;
Will result always be the floor of the division? What is the defined behavior?
Will result always be the floor of the division? What is the defined behavior?
Not quite. It rounds toward 0, rather than flooring.
6.5.5 Multiplicative operators
6 When integers are divided, the result of the / operator is the algebraic quotient with any
fractional part discarded.88) If the quotient a/b is representable, the expression
(a/b)*b + a%b shall equal a.
and the corresponding footnote:
This is often called ‘‘truncation toward zero’’.
Of course two points to note are:
3 The usual arithmetic conversions are performed on the operands.
and:
5 The result of the / operator is the
quotient from the division of the
first operand by the second; the
result of the % operator is the
remainder. In both operations, if the
value of the second operand is zero,
the behavior is undefined.
[Note: Emphasis mine]
Dirkgently gives an excellent description of integer division in C99, but you should also know that in C89 integer division with a negative operand has an implementation-defined direction.
From the ANSI C draft (3.3.5):
If either operand is negative, whether the result of the / operator is the largest integer less than the algebraic quotient or the smallest integer greater than the algebraic quotient is implementation-defined, as is the sign of the result of the % operator. If the quotient a/b is representable, the expression (a/b)*b + a%b shall equal a.
So watch out with negative numbers when you are stuck with a C89 compiler.
It's a fun fact that C99 chose truncation towards zero because that was how FORTRAN did it. See this message on comp.std.c.
Yes, the result is always truncated towards zero. It will round towards the smallest absolute value.
-5 / 2 = -2
5 / 2 = 2
For unsigned and non-negative signed values, this is the same as floor (rounding towards -Infinity).
Where the result is negative, C truncates towards 0 rather than flooring - I learnt this reading about why Python integer division always floors here: Why Python's Integer Division Floors
Will result always be the floor of the division?
No. The result varies, but variation happens only for negative values.
What is the defined behavior?
To make it clear floor rounds towards negative infinity,while integer division rounds towards zero (truncates)
For positive values they are the same
int integerDivisionResultPositive= 125/100;//= 1
double flooringResultPositive= floor(125.0/100.0);//=1.0
For negative value this is different
int integerDivisionResultNegative= -125/100;//=-1
double flooringResultNegative= floor(-125.0/100.0);//=-2.0
I know people have answered your question but in layman terms:
5 / 2 = 2 //since both 5 and 2 are integers and integers division always truncates decimals
5.0 / 2 or 5 / 2.0 or 5.0 /2.0 = 2.5 //here either 5 or 2 or both has decimal hence the quotient you will get will be in decimal.
I want to calculate the volume of a sphere using a Java program. So, I used
double result = 4/3*Math.PI*Math.pow(r,3);
This formula gives the wrong answers it seems.
Like Java program opt 4/3, but if I change it to
double result= Math.PI*Math.pow(r,3)*4/3;
it gives me the correct answer. Does any one know what is going on?
This has to do with the order in which casting occurs in Java (or C for that matter).
For the full details on operator precedence, see http://introcs.cs.princeton.edu/java/11precedence/.
In your first case, since the multiply and divide operators are computed from left to right, the first operation java interprets is 4/3. Since both operands are integer, java computes an integer division, the result of which is 1.
In your second case, the first operation is the double multiply: (Math.PIMath.pow(r,3)). The second operation multiplies a double (Math.PIMath.pow(r,3)) by an integer (4). This is performed by casting 4 to a double and performing a double multiply. Last, java has to divide a double (Math.PI*Math.pow(r,3)*4) by an integer (3), which java performs as a double division after casting 3 to a double. This gives you the result you expect.
If you want to correct your first answer, cast 3 to double first:
4/ (double)3
and you will get the result you expect.
The difference in the outcome is due to operator precedence. In Java, multiplication and division have equal precedence, and therefore are evaluated from left to right.
So, your first example is equivalent to
double result = (4/3)*Math.PI*Math.pow(r,3);
Here, 4/3 is a division of two integers, and in Java, in such cases integer division is performed, with outcome 1. To solve this, you have to explicitly make sure that one or both of the operands is a double:
double result = (4.0/3.0)*Math.PI*Math.pow(r,3);
Your second example, however, is equivalent to
double result = (Math.PI*Math.pow(r,3)*4)/3;
Here, the Math.PI*Math.pow(r,3)*4 part is evaluated to a double, and thus we have no integer division anymore and you get the correct result.
4/3 is a division between two int, so Java assumes that the result is also an int (in this case, this results in the value 1). Change it to 4.0/3.0 and you'll be fine, because 4.0 and 3.0 are interpreted as double by Java.
double result = 4.0 / 3.0 * Math.PI * Math.pow(r,3);
just a quick question and I'm probably gonna feel stupid for asking but still would like to know why it is so...!
Anyways, quick example:
x is a double.
double conversion = (x-32)*5/9;
This does the maths just fine.
double conversion = (x-32)*(5/9);
This isn't fine because the (5/9) is being treated as an int, thus result is overall 0.
double conversion = (x-32)*(5f/9f);
This does the maths just fine, as it explicitly makes the 5/9 values a float.
So my question is: Why does the first equation work perfectly fine? ( double conversion = (x-32)*5/9; )
Why isn't the 5/9 being made a 0 if it were an int supposedly? What makes the 5/9 different from (5/9) ?
The difference is between whether you do the multiplication first or the division first - and what the types of those operations are.
This:
(x - 32) * 5 / 9
is equivalent to:
((x - 32) * 5) / 9
So if the type of x is double, then the type of x - 32 is double, so the 5 is promoted to double, the multiplication is done in double arithmetic, giving a double result, and then the division is also done in double arithmetic.
Even if x is an integer type, you're doing the multiplication first, which will presumably give you a value bigger than 9 (in your test case), leaving you with a non-zero result. For example, if x is 45, then x-32 is 13, (x - 32) * 5 is 65, and the overall result is 7, then converted to 7.0 on assignment. That's not the same result you'll get if x is a double with the value 45.0, but it's still better than multiplying by 0...
You basically answered your own question. Evaluation order makes all the difference.
basic left to right evaluation results in different type casting than your explicit evaluation order in your second example
Assuming x is a double then your first equation divides a double by an integer due to order of operations.
(x-32) = y-> y*5 = z -> z/9
at each stage a double is being operated on, overriding integer arithmetic.
It is the order it's done in.
If you multiply by 5, you get a large number. If you then divide by 9, you still get an int,
But the remainder is discarded.
The reason is the order of the operations.
(x-32)*5/9 makes first (x-32)*5 and then divides the result by 9
(x-32)*(5/9) makes first (x-32) and (5/9). After both results are multiplied.
Your value of x might be double and it is making entire equation in double because brackets execute first.
It's a matter of when the conversion takes place. 5/9 consists of one 5 and one 9 (both ints) being divided with integer division. If either is a float (5f/9 or 5/9f) they will divide as floats.
When I perform simple math in java with doubles and other number data types, the double values seem to randomly vary a bit from the supposed result, which might be 5,59999999997 or 6,0000000002 or something. When I cast to int, the double value is obviously rounded down to the next whole number. Does this mean the double could be both 5 or 6? Or does that "5,999999999997" still count as 6 though which would be depending on the binary float value? If not, is there a way to let the negative vary be rounded up, but not lower values from 5,5 to 5,999999999996?
I mean, I dont really want to round the value as described in my last sentence. I'd like to always round down to the next whole number, but I don't want to cause an extra decrement due to wrong double math results.
Converting a double to an int always rounds down. You can round to the nearest whole integer via Math.round(double). The double is varying from what you expect because of floating point error.
If you want to round, you can use the round() method.
double d = 6 +/- some small error
long l = Math.round(d);
Or you can add 0.5 for positive numbers
long l = (long) (d + 0.5);
or
long l = (long) (d + (d < 0 ? -0.5 : 0.5));
I'm not sure I understand the question. Usually when you cast a double to int you add 0.5 to have a nice round.
From the Java Language Specification:
The Java programming language uses round toward zero when converting a floating value to an
integer (§5.1.3), which acts, in this case, as though the number were truncated, discarding
the mantissa bits. Rounding toward zero chooses at its result the format's value closest to
and no greater in magnitude than the infinitely precise result.
So 5,999999999997 when casted to an int will 5 and 6,0000000002 will be 6. If I understand what you are asking with having negative versions of the values (e.g. -5.97), I fail to see how
Math.round() does not suffice you. -6,0000000002 will be rounded to -6 as will -5,999999999997 and every other value above (but not including) -5.5.
This question already has answers here:
Is floating point math broken?
(31 answers)
Rounding oddity - what is special about "100"? [duplicate]
(2 answers)
Closed 9 years ago.
As I understand this, some numbers can't be represented with exactitude in binary, and that's why floating-point arithmetic sometimes gives us unexpected results; like 4.35 * 100 = 434.99999999999994. Something similar to what happens with 1/3 in decimal.
That makes sense, but this induces another question. Seems that in binary both 4.35 and 435 can be represented with exactitude. That's when it stops making sense to me. Why does 4.35 * 100 evaluates to 434.99999999999994? 435 and 4.35 have an exact representation in the double type dynamics:
double number1 = 4.35;
double number2 = 435;
double number3 = 100;
System.out.println(number1); // 4.35
System.out.println(number2); // 435.0
System.out.println(number3); // 100.0
// So far so good. Everything ok.
System.out.println(number1 * number3); // 434.99999999999994 !!!
// But 4.35 * 100 evaluates to 434.99999999999994
Why?
Edit: this question was marked as duplicate, and it is not. As you can see in the accepted answer, my confusion was regarding the discrepancy between the actual value and the printed value.
Seems that in binary both 4.35 and 435 can be represented with exactitude.
I see that you understand how the floating point numbers are internally represented. As for your doubt, no 4.35 does not have an exact binary representation. So the issue is, why the 1st print statement prints 4.35.
That is happening because System.out.println() invokes the Double.toString(double) method, which in turns uses FloatingDecimal#toJavaFormatString() method, which performs some rounding internally on the passed double argument. You can go through the source code I linked.
For seeing the actual value of 4.35, try using this:
BigDecimal bd = new BigDecimal(number1);
System.out.println(bd);
This will print:
4.3499999999999996447286321199499070644378662109375
In this case, rather than printing the double value, you create a BigDecimal object passing double value as argument. BigDecimal represents arbitrary precision signed decimal number. So it gives you the exact value of 4.35.
You are right in that sometimes floating-point arithmetic gives unexpected results.
Your assertion that 4.35 can be represented exactly in floating-point is incorrect, because it can't be represented as a terminating binary decimal. 100 can obviously be represented exactly, so for the result to be 434.99999999999994, `4.35 must not be represented exactly.
To be represented exactly in floating-point, a number must be able to be converted to a fraction where the denominator is a power of two only (and it must not be so precise that it exceeds the maximum precision of the floating-point type you're using). In this case, 4.35 is 4 7/20, and the denominator has a factor of 5, so the number can't be represented exactly in binary.
Although from a hardware perspective each floating-point number represents some exact value of the form M * 2^E (where M and E are integers in a certain range), from a software perspective it is more helpful to think of each floating-point number as representing "Something for which M * 2^E has been deemed the best representation, and which is hopefully close to that". Given a floating-point value (M * 2^E), one should figure that the actual number it's intended to represent may very easily be anywhere from (N - 1/2) * 2^E to (N + 1/2) * 2^E and in practice may extend a bit further beyond.
As a simple example, with type float, the value of M is limited to the range 0-16777215. The best representation of 2000000.1f is thus 16000001 * 2^-3 [i.e. 16000001/8]. Although exact decimal value of 16000001/8 is 2000000.125, the last digit isn't necessary to define the value of the number, since 16000001/8 would the best representation of 2000000.120 and 2000000.129 (or, for that matter, all values between 2000000.0625 and 2000000.1875, non-inclusive). Because the number of digits that would required to display the exact decimal value of a number of the form M * 2^E would often far exceed the number of meaningful digits, it is common to limit number of displayed digits to roughly those necessary to uniquely define the value.
Note that if one regards floating-point numbers as representing ranges, one will observe that casts from double to float--even though they must be explicitly specified--are actually safe since converting the double that best represents a particular value to float will yield either the best float representation of that value or something very close to it. Conversely, conversion from float to double, even though it's allowed implicitly, is dangerous because such conversion is very unlikely to select the double which would best represent the number that the float was supposed to represent.
it is a bit hard to explain in English, because I have learned computer number representation in Hungarian. In short, 4.35, 435 nor 100 is not exactly these numbers, but mantissa * 2^k (k-characteristic from -k to +k, and t - is the length of the mantissa in the M = (t,-k,+k) ) although the print call does some rounding. So the number-line is not continuous, but near some famous points, denser ).
So as I think these numbers are not exactly what you expect, and after the operation (I suppose this is one or two simple binary operation) you get the multiple of error distance of the two float point number representation.