Hi so i recently saw a question structured much like this
int a= (int) Math.pow(2,32);
System.out.println(a); //prints out Integer.MAX_VALUE
After i answered the question it turns out i got it wrong, i answered Integer.MIN_VALUE but the correct answer was Integer.MAX_VALUE. After further testing i realized any double that i cast to an int that is greater than Integer.MAX_VALUE just makes the int equal to Integer.MAX_VALUE.
For Example
int a = (int) ((double) Integer.MAX_VALUE+100);
System.out.println(a); //prints out Integer.MAX_VALUE
After further testing i realized if you try to cast a long to an int, it seems to assign the int to a seemingly random number.
So my question is. What the heck is going on, why does the double value not overflow the integer when you cast it to an int? and why does casting a long to an int return a seemingly random number
The logic of these conversions is part of the Java language specification, Item 5.1.3.
You can see there, that when converting from long to int, most significant bits are discarded, leaving the least significant 32 bits.
And also, that if the result of rounding a double or float is a number that is too small or too large to represent as an int (or long), the minimal or maximal representable number will be chosen.
There is no way for us here to answer "why" for a decision that has been made long ago. But this is the way the language is defined, and you can rely on it being the same in any Java environment you work in.
for casting a double value to integer it would erase the after point value and the the remainder is like rounding down the value of the double
and for the first question the int would return the value it could save in 8 bites so it would seem to be the min.value
long a= Math.pow(2,32); would give you the max.value
and for casting long to an integer It's not a random number. It's the rightmost 32 bits of the long number
sorry for my bad writing
english is my second language
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);
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);