Here is the specific equation that's giving me 0 when it should be giving me -0.4 (-2/5)
slope2 = ((yVals[i+2] - originY) / (xVals[i+2] - originX));
(-2 - 0) / (2 + 3)
slope2 is a double
yVals[] is an int array
origin is an int
Why does it keep returning 0? I know the variables are being called correctly because I've done a println on the different vals and they are correct.
You are performing integer division in Java, where math done using ints must yield an int, so the division truncates anything beyond the decimal point. This means that in Java, -2 / 5 is 0. It's not enough that the target of the assignment is a double. One of the operands must be double (or float) to force floating-point arithmetic.
Cast one of the operands to the / operator to a double to force floating-point arithmetic.
slope2 = ( (double) (yVals[i+2] - originY) / (xVals[i+2] - originX));
Related
I have this simple code and I need to understand why the right side of the equation has been casted to Integer before getting the result in type double.
The answer here is 1.0 so I don't understand why it's not 1.5.
int x = 2;
double y = 1 + 1/x;
System.out.println(y);
simply update your code as following since you are dealing with doubles.
int x = 2;
double y = 1 + 1.0/x;
System.out.println(y);
Notice: double y = 1 + 1/x;
Modify: double y = 1 + 1.0/x;
You'll get 1.5
here x is an int and 1 is also an int so calculation is done in int and so you are getting the answer as 1.0. To get as 1.5 you have to typecast 1 to double as 1.0. Then you will get as 1.5.
I think what you meant was: why the value of 'x' on the right-hand side has not been 'promoted' to a double?
First, change the second line to :
double y = 1 + (double) 1 / x;
//or
double y = 1 + 1.0 / x;
Details:
Simply for most computers to perform arithmetic operations operands must be of identical data types.
The cast operator (double) performs explicit conversion of its operand to double, then the variable ' x ' will be implicitly converted to a double which is called promotion.
also in the second line 1.0 is already a floating-point constant so you can guess that this is the same as before, that is a promotion to the variable 'x' will occur.
What you have done in your code is called Integer Division meaning that the fractional part of the division will be lost (truncated). Note that the fractional part is lost before it is assigned to the variable y.
You may have some intuition now on why we didn't write the code like that:
double y = 1.0 + 1 / x;
clearly, (1 / x) is still integer division ...hope that helps!
Like user markspace noted in a comment, the integer division happens because / has a higher order of precedence than =, which means that the division takes place first in the statement.
double y = 1 + (1/2); // Both 1 and 2 are integers at the time of operation.
// The above equation is the same as
double y = 1 + 0; // 1/2 equals 0 because integer division just keeps the integer value
// and gets rid of the value's decimal part.
Similar to what the other answers have shown, you can do something like one of the following:
double y = 1 + 1.0/x;
// Or
double y = 1 + 1/(double)x;
Just for simplicity, when I use integer literals when assigning double values, I just make all the integers have the .0 part. For example, instead of 1, I would always put 1.0. That way, you will never accidentally get unexpected results because of unwanted integer division.
Check out this page in the Java doc for the order of precedence for operators in Java.
arr[i]=s+t-Math.abs(s-j)/2;
here is the line, s= 600 j = 631 t =60 , the answer should be 645.5 but it prints 645.0.
arr[] is double
Assuming that the types of s and j are int, you must be performing Java's integer division, which results in an int. s-j results in -31, and the Math.abs overload that takes an int is called, and 31 is returned. Integer division in Java means that 31/2 is 15 the int, not 15.5 the double.
Use the floating-point literal 2.0 to force floating-point division (or cast one of the / operands to a double):
arr[i]=s+t-Math.abs(s-j)/2.0;
Its because you are losing precision while dividing ints .Put a cast around the division
arr[i]= s+ t- (double) Math.abs(s-j)/2;
Try putting.
arr[i]=s+t-Math.abs(s-j)/2.0;
The trick here is that when you do divide by 2 it will give you an integer answer. So for your case( Math.abs(-31)/2 -> 15 instead of 15.5. and thus will truncate the .5
Therefore, by adding the 2.0 it will give you a double answer that is 15.5 and give you the desired solution
Probably s-j is an integer-valued (or long-valued) expression in your example, which makes Java select an integer/long valued Math.abs(...) call, returning an integer/long value. When dividing integer values, the decimal places are truncated. For example, 3 / 2 becomes 1, 15 / 2 becomes 7.
An easy way to make the expression evaluated with floating point math, is to divide by 2.0 instead:
arr[i] = s + t - Math.abs(s-j) / 2.0;
These other writing styles will work too:
arr[i] = s + t - Math.abs(s-j) / 2.;
arr[i] = s + t - Math.abs(s-j) / 2f;
arr[i] = s + t - Math.abs(s-j) / 2d;
You should set 2f in order to make a decimal division (now you are doing a integer division in Math.abs(s-j)/2)
Then your code should be
arr[i] = s + t - Math.abs(s-j)/2f;
I'm a self-taught beginner in java and having trouble understanding ints and doubles when used in the same equation
For example,
int x;
double x;
i = 5;
x = i / 2 + 1.0; // (answer 3.0)
z = (int) 1.0 + i / 2.0; // (answer 3.5)
What is with the rounding?
The problem is that this operation:
i / 2
... is performing an integer division. That's why 5 / 2 gives as result 2, not 2.5. This is normal behavior in Java, to perform a floating-point division you must make sure that at least one of the operands is a floating-point literal:
5 / 2.0
Now the above will return 2.5, as expected. Alternatively, you can cast either one of the operands:
((double) i) / 2
A division involving two ints will yield an int (thus, 5 / 2 = 2). If you use a double in one of the operands, it will yield a double (thus 5 / 2.0 = 2.5). The rest is operation precedence.
i / 2 = int 2 because both operands are integers and so integer division operation is used (yielding integer result)
i / 2.0 = double 2.5 because i is first coerced to double (type of the other operand) and double division is used
This is a case between integer and decimal division.
When two integers are divided, integer division is performed, that is, where the numbers are divided and the decimal component truncated.
When any number of the two numbers in question is a decimal (double/float) every other number gets treated as a decimal such that given the expression 5 / 2.0. The result will be 2.5 returned in whatever type of object 2.0 was (double by default).
Given a mixed equation such as 5 / 2 + 1.0, operator precedence defines how the expression should be evaluated. Since division has a higher precedence than addition, 5 / 2 gets evaluated as a integer division, returning 2 as an integer.
This is then added to 1.0 where the 2 gets promoted to a double before evaluation, returning the number 3.0 as a double as the final result.
This question already has answers here:
Int division: Why is the result of 1/3 == 0?
(19 answers)
Closed 9 years ago.
I have a number of fields which take inputs, a process which happens and then fields that show the output. My issue is that for some reason math.round seems to be always rounding down instead of to the nearest integer.
Here is an example
private void method(){
int X= Integer.parseInt(XjTF.getText());
int Y= Integer.parseInt(YjTF.getText());
float Z =(X+Y)/6;
int output = Math.round(Z);
OutputjTF.setText(Integer.toString(output)+" =answer rounded to closest integer");
}
Your X and Y variables are int, so Java performs integer division, here when dividing by 6. That is what is dropping the decimal points. Then it's converted to a float before being assigned to Z. By the time it gets to Math.round, the decimal points are already gone.
Try casting X to float to force floating point division:
float Z =((float) X + Y)/6;
That will retain the decimal information that Math.round will use to properly round its input.
An alternative is to specify a float literal for 6, which will force the sum of X and Y to be cast to float before the division:
float Z = (X + Y)/6.0f;
It can't just be 6.0, because that's a double literal, and the Java compiler will complain about "possible loss of precision" when attempting to assign a double to a float.
Here's the relevant quote from the JLS, Section 15.17.2:
Integer division rounds toward 0. That is, the quotient produced for
operands n and d that are integers after binary numeric promotion
(§5.6.2) is an integer value q whose magnitude is as large as possible
while satisfying |d · q| ≤ |n|.
I came across a strange corner of Java.(It seems strange to me)
double dd = 3.5;
float ff = 3.5f;
System.out.println(dd==ff);
o/p: true
double dd = 3.2;
float ff = 3.2f;
System.out.println(dd==ff);
o/p: false
I observed that if we compare any two values (a float and a double as I mentioned in the example) with .5 OR .0 like 3.5, 234.5, 645.0
then output is true i.e. two values are equal otherwise output is false though they are equals.
Even I tried to make method strictfp but no luck.
Am I missing out on something.
Take a look at What every computer scientist should know about floating point numbers.
Squeezing infinitely many real numbers into a finite number of bits requires an approximate representation....
--- Edit to show what the above quote means ---
You shouldn't ever compare floats or doubles for equality; because, you can't really guarantee that the number you assign to the float or double is exact.
So
float x = 3.2f;
doesn't result in a float with a value of 3.2. It results in a float with a value of 3.2 plus or minus some very small error. Say 3.19999999997f. Now it should be obvious why the comparison won't work.
To compare floats for equality sanely, you need to check if the value is "close enough" to the same value, like so
float error = 0.000001 * second;
if ((first >= second - error) || (first <= second + error)) {
// close enough that we'll consider the two equal
...
}
The difference is that 3.5 can be represented exactly in both float and double - whereas 3.2 can't be represented exactly in either type... and the two closest approximations are different.
Imagine we had two fixed-precision decimal types, one of which stored 4 significant digits and one of which stored 8 significant digits, and we asked each of them to store the number closest to "a third" (however we might do that). Then one would have the value 0.3333 and one would have the value 0.33333333.
An equality comparison between float and double first converts the float to a double and then compares the two - which would be equivalent to converting 0.3333 in our "small decimal" type to 0.33330000. It would then compare 0.33330000 and 0.33333333 for equality, and give a result of false.
floating point is a binary format and it can represent numbers as a sum of powers of 2. e.g. 3.5 is 2 + 1 + 1/2.
float 3.2f as an approximation of 3.2 is
2 + 1 + 1/8+ 1/16+ 1/128+ 1/256+ 1/2048+ 1/4096+ 1/32768+ 1/65536+ 1/524288+ 1/1048576+ 1/4194304 + a small error
However double 3.2d as an approximation of 3.2 is
2 + 1 + 1/8+ 1/16+ 1/128+ 1/256+ 1/2048+ 1/4096+ 1/32768+ 1/65536+ 1/524288+ 1/1048576+ 1/8388608+ 1/16777216+ 1/134217728+ 1/268435456+ 1/2147483648+ 1/4294967296+ 1/34359738368+ 1/68719476736+ 1/549755813888+ 1/1099511627776+ 1/8796093022208+ 1/17592186044416+ 1/140737488355328+ 1/281474976710656+ 1/1125899906842624 + a smaller error
When you use floating point, you need to use appropriate rounding. If you use BigDecimal instead (and many people do) it has rounding built in.
double dd = 3.2;
float ff = 3.2f;
// compare the difference with the accuracy of float.
System.out.println(Math.abs(dd - ff) < 1e-7 * Math.abs(ff));
BTW the code I used to print the fractions for double.
double f = 3.2d;
double f2 = f - 3;
System.out.print("2+ 1");
for (long i = 2; i < 1L << 54; i <<= 1) {
f2 *= 2;
if (f2 >= 1) {
System.out.print("+ 1/" + i);
f2 -= 1;
}
}
System.out.println();
The common implementation of floating point numbers, IEEE754, allows for the precise representation of only those numbers which have a short, finite binary expansion, i.e. which are a sum of finitely many (nearby) powers of two. All other numbers cannot be precisely represented.
Since float and double have different sizes, the representation in both types for a non-representable value are different, and thus they compare as unequal.
(The length of the binary string is the size of the mantissa, so that's 24 for float, 53 for double and 64 for the 80-bit extended-precision float (not in Java). The scale is determined by the exponent.)
This should work:
BigDecimal ddBD = new BigDecimal(""+dd);
BigDecimal ffBD = new BigDecimal(""+ff);
// test for equality
ddBO.equals(ffBD);
Always work with BigDecimal when you want to compare floats or doubles
and always use the BigDecimal constructor with the String parameter!