Double milisecondsInYear = 365*24*3600*1000;
It's 1.7e9
But if I used
Double milisecondsInYear = 365*24*3600*1000.;
I got correct answer 3.15E10
Because 365, 24, 3600 and 1000 are all int literals, the calculation is done using ints. The multiplication overflows because the true value exceeds Integer.MAX_VALUE. By putting a dot at the end you turn that last literal into a double literal. This is not a very robust way to correct it because the multiplication of the first 3 numbers is still carried out using ints. The best way to deal with this is to make the first number a long or double literal.
365L*24*3600*1000
or
365.0*24*3600*1000
Because of overflow. 365*24*3600*1000 does not fit in an int (which is a signed 32-bit value). If you write that as 365L*24*3600*1000 then the necessary promotions will happen in the proper order and the result will be a long, which can fit that number.
In the second line, you have an extra character, the dot at the end - this makes the number a floating-point number, thus you lose in precision but you can actually do the multiplications.
Numbers in Java are ints, unless you specify otherwise.
When you add ., you'll have double calculations (since 1000.0 is double) instead of int, which fits (unlike int).
The first is performing integer math, because all of the numbers are integers the result is an integer (which is then widened to a double). The range of an int isn't sufficient for the result. A double or a long is. So, you could also use
double millisecondsInYear = (365L * 24 * 3600 * 1000);
System.out.println(millisecondsInYear);
to widen to long first. The above also outputs "3.1536E10".
The order or evaluation differes depending on the types you are using. That's why you get different answers.
Related
This question already has answers here:
Int division: Why is the result of 1/3 == 0?
(19 answers)
Closed 4 years ago.
This is a basic question but I can't find an answer. I've looked into floating point arithmetic and a few other topics but nothing has seemed to address this. I'm sure I just have the wrong terminology.
Basically, I want to take two quantities - completed, and total - and divide them to come up with a percentage (of how much has been completed). The quantities are longs. Here's the setup:
long completed = 25000;
long total = 50000;
System.out.println(completed/total); // Prints 0
I've tried reassigning the result to a double - it prints 0.0. Where am I going wrong?
Incidentally, the next step is to multiply this result by 100, which I assume should be easy once this small hurdle is stepped over.
BTW not homework here just plain old numskull-ness (and maybe too much coding today).
Converting the output is too late; the calculation has already taken place in integer arithmetic. You need to convert the inputs to double:
System.out.println((double)completed/(double)total);
Note that you don't actually need to convert both of the inputs. So long as one of them is double, the other will be implicitly converted. But I prefer to do both, for symmetry.
You don't even need doubles for this. Just multiply by 100 first and then divide. Otherwise the result would be less than 1 and get truncated to zero, as you saw.
edit: or if overflow is likely, if it would overflow (ie the dividend is bigger than 922337203685477581), divide the divisor by 100 first.
In Java
Integer/Integer = Integer
Integer/Double = Double//Either of numerator or denominator must be floating point number
1/10 = 0
1.0/10 = 0.1
1/10.0 = 0.1
Just type cast either of them.
Convert both completed and total to double or at least cast them to double when doing the devision. I.e. cast the varaibles to double not just the result.
Fair warning, there is a floating point precision problem when working with float and double.
If you don't explicitly cast one of the two values to a float before doing the division then an integer division will be used (so that's why you get 0). You just need one of the two operands to be a floating point value, so that the normal division is used (and other integer value is automatically turned into a float).
Just try with
float completed = 50000.0f;
and it will be fine.
As explain by the JLS, integer operation are quite simple.
If an integer operator other than a shift operator has at least one operand of type long, then the operation is carried out using 64-bit precision, and the result of the numerical operator is of type long. If the other operand is not long, it is first widened (§5.1.5) to type long by numeric promotion (§5.6).
Otherwise, the operation is carried out using 32-bit precision, and the result of the numerical operator is of type int. If either operand is not an int, it is first widened to type int by numeric promotion.
So to make it short, an operation would always result in a int at the only exception that there is a long value in it.
int = int + int
long = int + long
int = short + short
Note that the priority of the operator is important, so if you have
long = int * int + long
the int * int operation would result in an int, it would be promote into a long during the operation int + long
As your output results a double you should cast either completed variable or total variable or both to double while dividing.
So, the correct implmentation will be:
System.out.println((double)completed/total);
This question already has answers here:
Int division: Why is the result of 1/3 == 0?
(19 answers)
Closed 4 years ago.
This is a basic question but I can't find an answer. I've looked into floating point arithmetic and a few other topics but nothing has seemed to address this. I'm sure I just have the wrong terminology.
Basically, I want to take two quantities - completed, and total - and divide them to come up with a percentage (of how much has been completed). The quantities are longs. Here's the setup:
long completed = 25000;
long total = 50000;
System.out.println(completed/total); // Prints 0
I've tried reassigning the result to a double - it prints 0.0. Where am I going wrong?
Incidentally, the next step is to multiply this result by 100, which I assume should be easy once this small hurdle is stepped over.
BTW not homework here just plain old numskull-ness (and maybe too much coding today).
Converting the output is too late; the calculation has already taken place in integer arithmetic. You need to convert the inputs to double:
System.out.println((double)completed/(double)total);
Note that you don't actually need to convert both of the inputs. So long as one of them is double, the other will be implicitly converted. But I prefer to do both, for symmetry.
You don't even need doubles for this. Just multiply by 100 first and then divide. Otherwise the result would be less than 1 and get truncated to zero, as you saw.
edit: or if overflow is likely, if it would overflow (ie the dividend is bigger than 922337203685477581), divide the divisor by 100 first.
In Java
Integer/Integer = Integer
Integer/Double = Double//Either of numerator or denominator must be floating point number
1/10 = 0
1.0/10 = 0.1
1/10.0 = 0.1
Just type cast either of them.
Convert both completed and total to double or at least cast them to double when doing the devision. I.e. cast the varaibles to double not just the result.
Fair warning, there is a floating point precision problem when working with float and double.
If you don't explicitly cast one of the two values to a float before doing the division then an integer division will be used (so that's why you get 0). You just need one of the two operands to be a floating point value, so that the normal division is used (and other integer value is automatically turned into a float).
Just try with
float completed = 50000.0f;
and it will be fine.
As explain by the JLS, integer operation are quite simple.
If an integer operator other than a shift operator has at least one operand of type long, then the operation is carried out using 64-bit precision, and the result of the numerical operator is of type long. If the other operand is not long, it is first widened (§5.1.5) to type long by numeric promotion (§5.6).
Otherwise, the operation is carried out using 32-bit precision, and the result of the numerical operator is of type int. If either operand is not an int, it is first widened to type int by numeric promotion.
So to make it short, an operation would always result in a int at the only exception that there is a long value in it.
int = int + int
long = int + long
int = short + short
Note that the priority of the operator is important, so if you have
long = int * int + long
the int * int operation would result in an int, it would be promote into a long during the operation int + long
As your output results a double you should cast either completed variable or total variable or both to double while dividing.
So, the correct implmentation will be:
System.out.println((double)completed/total);
This question already has answers here:
Int division: Why is the result of 1/3 == 0?
(19 answers)
Closed 4 years ago.
This is a basic question but I can't find an answer. I've looked into floating point arithmetic and a few other topics but nothing has seemed to address this. I'm sure I just have the wrong terminology.
Basically, I want to take two quantities - completed, and total - and divide them to come up with a percentage (of how much has been completed). The quantities are longs. Here's the setup:
long completed = 25000;
long total = 50000;
System.out.println(completed/total); // Prints 0
I've tried reassigning the result to a double - it prints 0.0. Where am I going wrong?
Incidentally, the next step is to multiply this result by 100, which I assume should be easy once this small hurdle is stepped over.
BTW not homework here just plain old numskull-ness (and maybe too much coding today).
Converting the output is too late; the calculation has already taken place in integer arithmetic. You need to convert the inputs to double:
System.out.println((double)completed/(double)total);
Note that you don't actually need to convert both of the inputs. So long as one of them is double, the other will be implicitly converted. But I prefer to do both, for symmetry.
You don't even need doubles for this. Just multiply by 100 first and then divide. Otherwise the result would be less than 1 and get truncated to zero, as you saw.
edit: or if overflow is likely, if it would overflow (ie the dividend is bigger than 922337203685477581), divide the divisor by 100 first.
In Java
Integer/Integer = Integer
Integer/Double = Double//Either of numerator or denominator must be floating point number
1/10 = 0
1.0/10 = 0.1
1/10.0 = 0.1
Just type cast either of them.
Convert both completed and total to double or at least cast them to double when doing the devision. I.e. cast the varaibles to double not just the result.
Fair warning, there is a floating point precision problem when working with float and double.
If you don't explicitly cast one of the two values to a float before doing the division then an integer division will be used (so that's why you get 0). You just need one of the two operands to be a floating point value, so that the normal division is used (and other integer value is automatically turned into a float).
Just try with
float completed = 50000.0f;
and it will be fine.
As explain by the JLS, integer operation are quite simple.
If an integer operator other than a shift operator has at least one operand of type long, then the operation is carried out using 64-bit precision, and the result of the numerical operator is of type long. If the other operand is not long, it is first widened (§5.1.5) to type long by numeric promotion (§5.6).
Otherwise, the operation is carried out using 32-bit precision, and the result of the numerical operator is of type int. If either operand is not an int, it is first widened to type int by numeric promotion.
So to make it short, an operation would always result in a int at the only exception that there is a long value in it.
int = int + int
long = int + long
int = short + short
Note that the priority of the operator is important, so if you have
long = int * int + long
the int * int operation would result in an int, it would be promote into a long during the operation int + long
As your output results a double you should cast either completed variable or total variable or both to double while dividing.
So, the correct implmentation will be:
System.out.println((double)completed/total);
This question already has answers here:
Int division: Why is the result of 1/3 == 0?
(19 answers)
Closed 4 years ago.
This is a basic question but I can't find an answer. I've looked into floating point arithmetic and a few other topics but nothing has seemed to address this. I'm sure I just have the wrong terminology.
Basically, I want to take two quantities - completed, and total - and divide them to come up with a percentage (of how much has been completed). The quantities are longs. Here's the setup:
long completed = 25000;
long total = 50000;
System.out.println(completed/total); // Prints 0
I've tried reassigning the result to a double - it prints 0.0. Where am I going wrong?
Incidentally, the next step is to multiply this result by 100, which I assume should be easy once this small hurdle is stepped over.
BTW not homework here just plain old numskull-ness (and maybe too much coding today).
Converting the output is too late; the calculation has already taken place in integer arithmetic. You need to convert the inputs to double:
System.out.println((double)completed/(double)total);
Note that you don't actually need to convert both of the inputs. So long as one of them is double, the other will be implicitly converted. But I prefer to do both, for symmetry.
You don't even need doubles for this. Just multiply by 100 first and then divide. Otherwise the result would be less than 1 and get truncated to zero, as you saw.
edit: or if overflow is likely, if it would overflow (ie the dividend is bigger than 922337203685477581), divide the divisor by 100 first.
In Java
Integer/Integer = Integer
Integer/Double = Double//Either of numerator or denominator must be floating point number
1/10 = 0
1.0/10 = 0.1
1/10.0 = 0.1
Just type cast either of them.
Convert both completed and total to double or at least cast them to double when doing the devision. I.e. cast the varaibles to double not just the result.
Fair warning, there is a floating point precision problem when working with float and double.
If you don't explicitly cast one of the two values to a float before doing the division then an integer division will be used (so that's why you get 0). You just need one of the two operands to be a floating point value, so that the normal division is used (and other integer value is automatically turned into a float).
Just try with
float completed = 50000.0f;
and it will be fine.
As explain by the JLS, integer operation are quite simple.
If an integer operator other than a shift operator has at least one operand of type long, then the operation is carried out using 64-bit precision, and the result of the numerical operator is of type long. If the other operand is not long, it is first widened (§5.1.5) to type long by numeric promotion (§5.6).
Otherwise, the operation is carried out using 32-bit precision, and the result of the numerical operator is of type int. If either operand is not an int, it is first widened to type int by numeric promotion.
So to make it short, an operation would always result in a int at the only exception that there is a long value in it.
int = int + int
long = int + long
int = short + short
Note that the priority of the operator is important, so if you have
long = int * int + long
the int * int operation would result in an int, it would be promote into a long during the operation int + long
As your output results a double you should cast either completed variable or total variable or both to double while dividing.
So, the correct implmentation will be:
System.out.println((double)completed/total);
I have to do an operation with integers, very simple:
a=b/c*d
where all the variables are integer, but the result is ZERO whatever is the value of the parameters. I guess that it's a problem with the operation with this type of data (int).
I solved the problem converting first in float and then in integer, but I was wondering if there is a better method.
The / operator, when used with integers, does integer division which I suspect is not what you want here. In particular, 2/5 is zero.
The way to work around this, as you say, is to cast one or more of your operands to e.g. a float, and then turn the resulting floating point value back into an integer using Math.floor, Math.round or Math.ceil. This isn't really a bad solution; you have a bunch of integers but you really do want a floating-point calculation. The output might not be an integer, so it's up to you to specify how you want to convert it back.
More importantly, I'm not aware of any syntax to do this that would be more concise and readable than (for example):
a = Math.round((float)b / c * d)
In this case, you can reorder the expression so division is performed last:
a = (b*d)/c
Be careful that b*d won't ever be large enough to overflow an int. If it might be, you could cast one of them to long:
a = (int)(((long)b*d)/c)