Unexpected result in long/int division - java

I have values like this:
long millis = 11400000;
int consta = 86400000;
double res = millis/consta;
The question is: why res equals 0.0 (instead of ca. 0.131944)? It's stored in double so there should be no rounding right?

When you are using a binary operator, both arguments should be of a same type and the result will be in their type too. When you want to divide (int)/(long) it turns into (long)/(long) and the result is (long). you shouldmake it (double)/(long) or (int)/(double) to get a double result. Since double is greater that int and long, int and long will be turned into double in (double)/(long) and (int)/(double)

Because you are dividing a long by an int you get an long results.
What you are effectively doing is
double res = (double) (millis/consta);
as millis/consta is 0, when cast to double is 0.0
Try the following to divide a double by an int and get a double result.
double res = (double) millis/consta;
which is the same as
double res = ((double) millis)/((double) consta));

You are doing longdivision (int gets cast to long) so you get long values, which are integers (so, 0)
You should do
double res = (double) millis / consta;
Once one of the values is casted to double, the other is too casted so the operation uses the same type in both operators.

millis/consta is an integer division, which results in 0. the casting in the line:
double res = millis/consta;
is done on the result:
double res = (double)(millis/consta);
What you need to do is to cast one of the operands:
double res = (double)millis/consta;

The resulting type of a long and int devision will be a long, which can't hold decimals.
you want to cast it to a double before you assign it

When this happens it automatically downcasts to int to perform the operation. Thy writing it like:
long millis = 11400000;
int consta = 86400000;
double res = ((double)millis)/((double)consta);
And it will work.

This is because
long: The long data type is a 64-bit signed two's complement integer.
int: The int data type is a 32-bit signed two's complement integer.
See Primitive type
It means both are integer.
Since we divide long by integer, result is long 0.
But you assign this value to res(double) value and print it.
So the result 0.0 is shown.
long millis = 11400000;
int consta = 86400000;
System.out.println("millis/consta = " + millis/consta); // print 0
double res = millis/consta;
System.out.println("Res " + res); // print 0.0

Related

How can I convert a decimal string value to int in java

I'm trying to convert a string "3.0" to int in java. I tried to convert using Integer.parseInt, but it throws an exception. Any idea how can I convert the string with decimal values to int in java and kotlin
String value = "3.0";
int i = Integer.parseInt(value);
In kotlin you can do this as
val str = "3.0"
val result = str.toDouble().toInt()
Convert the string to an integer, then parse:
int i = Integer.parseInt(str.replaceAll("\\..*", ""));
This removes the dot and everything after it, which is effectively what casting a floating point type to integer does.
String value = "3.0";
int i = (int) Float.parseFloat(value);
You can't parse "3.0" as an integer, because it represents a floating-point value. Your best bet is to parse it as such using the handy build-in functions (Double.parseDouble("3.0") or Float.parseFloat("3.0")) and then convert that to an integer.
How you convert it depends on how you want to treat the decimal portion
discard it (number moves closer to zero): cast to int
(int) 2.5 = 2, (int) -2.5 = -2
round it to the nearest integer: Math.round(), then cast*
(int) Math.round(2.5) = 3, (int) Math.round(-2.5) = -3
round to the higher integer (number moves towards positive infinity): Math.ceil() then cast
(int) Math.ceil(2.5) = 3, (int) Math.ceil(-2.5) = 2
round to the lower integer (number moves towards negative infinity):
Math.floor() then cast
(int) Math.floor(2.5) = 2, (int) Math.floor(-2.5) = -3
*Math.round takes either a float or a double, and produces an int or a long respectively, so you don't need cast to int if you use a float. All the other Math methods take doubles though, so I'm using that for consistency
Kotlin is the same, the equivalents are:
parse: "2.5".toDouble()
discard decimal: 2.5.toInt()
round to nearest: 2.5.roundToInt()
round to higher: ceil(2.5).toInt()
round to lower: floor(2.5).toInt()
(functions are in kotlin.math)

The effect of assigning parameter types on integer overflow

I am having difficulty of understanding the behavior of the java in the following scenario. For example, I have a multiply method, which simply multiplies two int value and print the result to the screen.
private static void multiply() {
int firstValue = Integer.MAX_VALUE;
int secondValue = 2; //double secondValue=2
double result = firstValue * secondValue;
System.out.println("Result is: " + result);
}
and because of the fact that Integer overflow, the result is -2. However, here the calculation result is assigned to a double, which accepts much bigger value than than multiplication of firstValue and secondValue.
My questions to this issue are;
1- Why is Integer overflow happening, although the result is assigned to a double?
2- When I change the type of secondValue to double (mentioned in the comment), the result is correct. Why do Java behave differently when the type of one of the multiplier is changed to double?
Java does not support target type casting.
private static void multiply() {
int firstValue = Integer.MAX_VALUE;
int secondValue = 2;
double one = 1.0;
double result = one * firstValue * secondValue;
System.out.println("Result is: " + result);
}
Target Type casting means casting the value of result to the type of the variable it has to be assigned to.
So it does not know that the result has to be assigned to a double variable. In this case, int is the biggest data type, so the expression is calculated in int data type.
if you multiply it with double one, the expression is calculated in double type and the answer is correct.
The result of multiplying two ints is an int, which may or may not overflow, depending on the value of the multiplication. Once this result is produced, it's only then promoted to a double, after the overflow may have occurred.
If one of the operands is a double, the result of the multiplication would be a double, which allows for a much larger range than an int.
this is expected because when you are multiplying 2 integers the result is an integer only. It works with the otherway when you use double as one of the field the result will be considerd as a double value. the receivers data type doesn't matter here

Math floor mixing types error?

I have this:
String a = tonsescolhidos.getValue().toString();
int tons = Integer.parseInt(a);
float distlevel = 256/(tons - 1);
int temp;
temp = Math.floor(((float) (tons / distlevel) + 0.5)*distlevel);
tons = temp;
I get the error: "Incompatible types: possible lossy conversion from double to int" in the 5th line. How do i cast the variables in the right way.. what am I missing?
Math.floor only has one overload: double Math.floor(double). That always returns a double.
You would need to explicitly cast it to an int:
temp = (int) Math.floor(...);
But note that it is potentially lossy: double can store values too large to store in an int. So, you need to ensure that it's not a lossy operation by ensuring that the double's value is between Integer.MIN_VALUE and Integer.MAX_VALUE, by constraining the inputs appropriately.
Alternatively, rearrange your calculation so that you can do it all in integer math.

Make Long Variable Return Decimal Answer in Java

How do you make Long return decimal?
long i = 10;
long g = 1028;
long gf =(long) i/ (long)g;
System.out.println(gf)
Current answer:
0
Desire Answer :
0.001 // round to 0.000
Integer arithmetic truncates fractional parts of a division. You need a double, and you need to cast an operand to double to create a floating point result:
double gf = (double) i / g;
The JLS Section 4.2.4 defines:
If at least one of the operands to a numerical operator is of type double, then the operation is carried out using 64-bit floating-point arithmetic, and the result of the numerical operator is a value of type double. If the other operand is not a double, it is first widened (§5.1.5) to type double by numeric promotion (§5.6).
Try this one:
long i = 10;
long g = 1028;
double gf = (double) i / (double) g;
System.out.println(gf);
By definition a long is an integer.
However you can treat a long as a fixed-point decimal, just by dividing or multiplying wherever necessary. For example, let's say that gf is a count of the number of millionths.
long i = 10;
long g = 1028;
long gf = (100000 * i ) / g;
System.out.println(String.format("%d.%06d", gf / 1000000, gf % 1000000));
Alternatively, use a floating-point type like float or double -- always being aware of the risks caused by rounding errors.

How can i convert Integer value to decimal value?

i have an Integer value:
Integer value = 56472201;
Where the value could be positive or negative.
When I divide the value by 1000000, I want this result in the form 56.472201 but instead it gives me just the quotient. How am I able to get both the quotient and remainder values?
cast it to float and then do it:
int i = 56472201;
float j = ((float) i)/1000000.0
Edit: Due to precision(needed in your case), use double. Also as pointed by Konrad Rudolph, no need for explicit casting:
double j = i / 1000000.0;
You have to convert the value to a floating point type first, otherwise you will be doing an integer division.
Example in C#:
int value = 56472201;
double decimalValue = (double)value / 1000000.0;
(The cast is actually not needed in this code, as dividing by a floating point number will cast the value to match, but it's clearer to write out the cast in the code as that is what actually happens.)
If you divide an int by a double you will be left with a double result as illustrated by this unit test.
#Test
public void testIntToDouble() throws Exception {
final int x = 56472201;
Assert.assertEquals(56.472201, x / 1e6d);
}
1e6d is 1 * 10^6 represented as a double

Categories

Resources