I had to calculate this: 1*5000*500/(10000*24645.16239360158)
But then realized I should multiply it by 1000. I get 2 different answers depending on how I do it. I'm not sure why, though, as the placement of parentheses shouldn't matter for multiplication. Would appreciate any insight!
System.out.println(Double.toString(1000*1*5000*500/(10000*24645.16239360158)));
outputs
-7.283243937828597
for sure incorrect because it's negative
System.out.println(Double.toString(1000*(1*5000*500/(10000*24645.16239360158))));
on the other hand, outputs
10.143978603480635
(correct)
Basically in the second case we multiply the result by a 1000 after we've calculated it, and that somehow works.
Thanks!
You need to know that int * int yields an int (5 * 5). And int * double yields an double (5 * 5.0).
As you probably know, those data types have different maximal sizes and store values in a different way.
Here are some of them:
You can use Integer.MAX_VALUE and Integer.MIN_VALUE for the exact bounds.
If you need to exceed those values, but also want to have an int, you should use the class BigInteger. It can handle arbitrary big integers.
Else you will have what is called an overflow, when you do Integer.MAX_VALUE + 1 the result will be Integer.MIN_VALUE. If you recall how this number is stored in bytes, for example something like 111 then +1 would return 1000 but there is no place to store the first 1, you'll receive 000 which is the MIN_VALUE.
You also should know that when you compute 5 / 2 it will not return 2.5 but 2, as you divide two int, the result will also be an int. If you want to have a double, then you need to do something like this 5 / 2.0 or (5 + 0.0) / 2.
this expression 1000*1*5000*500/(10000*24645.16239360158),first calculate 1000*1*5000*500,the result is -1794967296,overflow.
this expression 1000*(1*5000*500/(10000*24645.16239360158)) overflow do not happend.
The evaluation of any expression is done by operator precedence parser. If you want to change the priority of precedence, You would've to use parentheses.
In the first case '/' and '*' having same priority table.
In second case '*' is getting some priority over '/'. Thats why your getting diffrent values as output.
It is because of Java's implicit type casting. By default Java would use int. As user2357112 commented, the number is too large for int.
If you want your first version to work, add a "d" to tell Java to use a double.
Double d = 1000d*1*5000*500/(10000*24645.16239360158)
System.out.println(d);
You'd get:
10.143978603480635
Related
This question already has answers here:
How to make the division of 2 ints produce a float instead of another int?
(9 answers)
Closed 7 years ago.
double multiply()
{
double x=(2/3)*3.14*1.02;
System.out.print(x);
double y=0.666*3.14*1.02; /*(2/3)=0.666...*/
System.out.print(y);
}
Output:
x=0.0
y=SomeNumber
please explain this?
(2/3) is 0.
because both are integers. To solve this, use a cast or make it clear that your number is not an integer:
double x=(2/3d)*3.14*1.02;
Now you have an integer divided by a double, which results in a double.
Some more to read about this:
http://www.mathcs.emory.edu/~cheung/Courses/170/Syllabus/04/mixed.html
(2/3) is computed first (because of the parentheses), and in integer arithmetic (since the number literals are of type int). The fractional part is discarded.
It is therefore an int type with a value of 0. The entire expression is therefore zero.
The obvious remedy is to remove the parentheses and write 2.0 / 3.0 instead. Some folk prefer an explicit cast, but I find that ugly.
2/3 = 0 because they don't have explicit cast to double they are integers. The whole expression becomes: double x=0*3.14*1.02;
which is 0.
because data type of both 2 and 3 is int and int/int gives you int which in your case 2/3 is 0.
Try using 2.0/3 or 2/3.0 you will get the required answer.
Suffix every number with a 'd' to be sure you are dealing with doubles
I'm trying to use Junit to test a java program, and I'm not sure how to go about testing for upper-bound violations.
Specifically, I have written a simple program to convert between kilometers and miles.
For example, here is the method for converting from miles to kilometers
public static double mileToKm(double mile){
//1.1170347260596139E308 / 0.621371192 = Double.MAX_VALUE
try{
if (mile < 0 || mile > 1.1170347260596139E308){
throw new IllegalArgumentException();
}
else
return mile / 0.621371192;}
return 0;
}
So, I guess my question is two-fold: First, why is it that I can't conjure up an exception when I try
mileToKm(1.1170347260596139E308 + 1)
in junit? I assume it's a rounding issue, but if that's the case then how can I get the exception thrown?
Second, for the method to convert from km to mile, I want to throw an exception if the parameter is greater than Double.MAX_VALUE. How can I pass such a parameter? I can get the Junit test to pass if I just pass as parameter Double.MAX_VALUE * 10, but I also get a message in the Console (this is all in Eclipse Mars 4.5.1, btw) saying 'MAX = 1.7976931348623157E308'. The parameter has to be a double so it can't be BigDecimal or something like that.
OK, I lied, the question is three-fold. What's up with this:
double value = Double.MAX_VALUE * 0.621371192; //max_value * conversion factor
System.out.println(value);
prints 1.1170347260596138E308, but then these two statements
System.out.println(value / 0.621371192);
System.out.println(Double.MAX_VALUE);
print 1.7976931348623155E308 and 1.7976931348623157E308, respectively. In other words, I would expect these two values to both be equivalent to Double.MAX_VALUE, but the first statement has a 5 right before the E, instead of a 7. How can I fix this? Thanks so much, hope this isn't too prolix.
You're confused about floating point numbers.
Firstly, the number 1.1170347260596139E308 + 1 is not representable using primitives in Java, as doubles have ~16 significant digits, and that addition requires 308 significant digits.
Secondly, float/double operations are not idempotent if you use intermediate storage (and most of the times even without it). Floating point operations lose accuracy, and arithmetic methods that retain accuracy over large computations (think weather models) are sought after in the scientific sector.
Thirdly, there's Double.MAX_VALUE, which represents the largest representable number in a primitive in Java; the only other value X such that X > Double.MAX_VALUE can hold is Double.POSITIVE_INFINITY, and that's not a real number.
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.
This question already has answers here:
math.random, only generating a 0?
(4 answers)
Closed 8 years ago.
This piece of code is giving the result I wanted
double a=Math.random()*100;
int b=(int)a;
System.out.println(b);
but when I did for the same thing this way, it is giving zero always
int a=(int)Math.random()*100;
System.out.println(a);
As far as I know typecasting will store the bigger data-type to small. but in the later code, I'm gettig zero every single time I run the program.
(int)Math.random()*100; means:
cast the value of 'Math.random()' to int and then multiple by 100. Since Math.random returns a number between 0 and 1 casting to int will always chop off the decimal path and give you 0.
The correct way to do it is
(int)(Math.random()*100);
Try with,
int a=(int)(Math.random()*100);
System.out.println(a);
Math.random() Returns a double value with a positive sign, greater than or equal to 0.0 and less than 1.0. Returned values are chosen pseudorandomly with (approximately) uniform distribution from that range.
Type casting is both right-to-left associative, and has a higher precedence than multiplication.
Source
Let me break it down a bit.
Like any other operator, a type cast has a certain level of priority attached to it. Certain operators have higher priority than others, and certain operators associate with their arguments in a certain way. For example, numerical operations are typically left-to-right associative; that is, with operators of an equal priority, one can parenthesize them from the left and get the same result.
Example:
5 * 5 * 5 / 3 + 5 -> (((5) * 5) * 5) / 3) + 5
Right-to-left associativity would allow you to parenthsize the operations from the right to achieve the same result.
Example:
int x;
int y;
int z;
x = y = z = 10 -> x = (y = (z = (10))
Type casting, much like assignment, is right-to-left associative, so it's going to essentially use the rightmost argument to satisfy its closest association, then progress backwards through the chain until you reach the ultimate goal.
This means that you could write this as valid syntax, although it would be very strange:
Object foo = (Object)(Number)(float)Math.random();
First, we cast our result from a double to a float, then to a Number, then to an Object (which is totally redundant, but possible).
The priority bit in particular is what causes the multiplication to apply last in this chain of events.
Bear in mind, in no one level of priority does the language intermingle associativity. That means an operator at level 1 priority associates in a specific way, and operators in level 2 operate in a specific way.
So, we come now to your expression:
int a = (int) Math.random() * 100;
Casting has a priority level of 3. The mathematical operator * has a priority level of 4. So, Java sees your statement like this:
int a = ((int) Math.random()) * 100;
The parentheses are there for extra clarity. (Note that parentheses have the highest priority.)
What you want to do, as explained more tersely in other answers, is use the parentheses to force your intended priority instead of letting Java decide. So, you would write this instead:
int a = (int) (Math.random() * 100);
This forces Java to evaluate the multiplication before the cast, since the parentheses have a higher priority than the cast.
Because the cast to int happens before the multiplication and as Math.random() generates a number between 0 (inclusive) and 1 (exclusive), it is rounded to 0.
You are casting before multiplying here...
Math.random() will generate number between 0 and 1 and will be rounded to 0 before multiplying with 100.
(int)(Math.random()*100) will behave as you want.
Consider using java.util.Random:
Random random = new Random();
int value = random.nextInt(100);
System.out.println(value);
Random is thread-safe, whereas Math.Random() is not.
When testing, you can feed a Random the same seed to generate reproducible pseudorandom numbers. You can't with Math.Random().
and more.
See more here: Math.random() versus Random.nextInt(int)
use this :
int a=(int)(Math.random()*100);
System.out.println(a);
Why does the below code prints 2147483647, the actual value being 2147483648?
i = (int)Math.pow(2,31) ;
System.out.println(i);
I understand that the max positive value that a int can hold is 2147483647. Then why does a code like this auto wraps to the negative side and prints -2147483648?
i = (int)Math.pow(2,31) +1 ;
System.out.println(i);
i is of type Integer. If the second code sample (addition of two integers) can wrap to the negative side if the result goes out of the positive range,why can't the first sample wrap?
Also ,
i = 2147483648 +1 ;
System.out.println(i);
which is very similar to the second code sample throws compile error saying the first literal is out of integer range?
My question is , as per the second code sample why can't the first and third sample auto wrap to the other side?
For the first code sample, the result is narrowed from a double to an int. the JLS 5.1.3 describes how narrowing conversions for doubles to ints are performed.
The relevant part is:
The value must be too large (a
positive value of large magnitude or
positive infinity), and the result of
the first step is the largest
representable value of type int or
long.
This is why 2^31 (2147483648) is reduced to Integer.MAX_VALUE (2147483647). The same is true for
i = (int)(Math.pow(2,31)+100.0) ; // addition note the parentheses
and
i = (int)10000000000.0d; // == 2147483647
When the addition is done without parentheses, as in your second example, we are then dealing with integer addition. Integral types use 2's complement to represent values. Under this scheme adding 1 to
0x7FFFFFFF (2147483647)
gives
0x80000000
Which is 2's complement for -2147483648. Some languages perform overflow checking for arithmetic operations (e.g. Ada will throw an exception). Java, with it's C heritage does not check for overflow. CPUs typically set an overflow flag when an arithmetic operation overflows or underflows. Language runtimes can check this flag, although this introduces additional overhead, which some feel is unnecessary.
The third example doesn't compile since the compiler checks literal values against the range of their type, and gives a compiler error for values out of range. See JLS 3.10.1 - Integer Literals.
Then why does a code like this auto wraps to the negative side and prints -2147483648?
This is called overflow. Java does it because C does it. C does it because most processors do it. In some languages this does not happen. For example some languages will throw an exception, in others the type will change to something that can hold the result.
My question is , as per the second code sample why can't the first and third sample auto wrap to the other side?
Regarding the first program: Math.pow returns a double and does not overflow. When the double is converted to an integer it is truncated.
Regarding your third program: Overflow is rarely a desirable property and is often a sign that your program is no longer working. If the compiler can see that it gets an overflow just from evaluating a constant that is almost certainly an error in the code. If you wanted a large negative number, why would you write a large positive one?