This is a question from Vodoo exam, class TestVodoo2 { public static void main(String[] arg) { System.out.println("Abs()="+Math.abs(-17)+Math.abs(Integer.MIN_VALUE)); } } When we pass -17 to Abs() it returns 17 But when we pass MIN_VALUE we still get a negative value (-2147483648) Why is it so? Thanks.

Let me answer a question with a question... What is the range of an int? Answer that, and I'll bet you be able to understand this question. If you're still confused, let me know. Corey

Corey, Thanks The range is -2147483648 to 2147483647 But no, still far away from answer. This time i tried the following: System.out.println(Math.abs(Byte.MIN_VALUE)); answer:128

Corey McGlone
Ranch Hand

Joined: Dec 20, 2001
Posts: 3271

posted

0

So, what do you think the result should be if you pass Integer.MIN_VALUE to the abs method? Is that value within the range on an int?

See API documentation <quote> public static int abs(int a) Returns the absolute value of an int value. If the argument is not negative, the argument is returned. If the argument is negative, the negation of the argument is returned. Note that if the argument is equal to the value of Integer.MIN_VALUE, the most negative representable int value, the result is that same value, which is negative. </quote> its can't be +2147483648 for sure since thats not in the range of an int( which is the return type of the function).

Siddhartha Bhattacharya
Ranch Hand

Joined: Jul 02, 2002
Posts: 36

posted

0

System.out.println(Math.abs(Byte.MIN_VALUE)); Byte promoted to int. so the result is abs(-128) which is 128. still within the range of int.

can anybody pls provide me with the URL for Vodoo exam,vodoo page. Is it free ??

please use the [code][/code] tags when showing code. visit <a href="http://saloon.javaranch.com/cgi-bin/ubb/ultimatebb.cgi?ubb=ubb_code_page" target="_blank" rel="nofollow">http://saloon.javaranch.com/cgi-bin/ubb/ultimatebb.cgi?ubb=ubb_code_page</a> ,for more details

Just to sum up the entire conversation, the problem is that, when using two's complement to store values, the range for each data type goes from -n to n-1. Therefore, there is one more negative number than there is a positive number. You can account for this when you realize that 0 is considered a positive number in two's complement (the sign bit is positive). Therefore, if you try to take the absolute value of the most negative value, the answer will be a number which is outside of the range of the data type. This causes overflow. In this case, we take Integer.MIN_VALUE, which is this:

And we try to take the absolute value of it. That means we need to flip all the bits and add 1. So, we first flip all the bits and we get this:

Now, we add 1, and we get:

Notice, we ended up with the same value we started with. I hope that helps clear up any remaining confusion. Corey

the output shows Integer.MIN_VALUE and Long.MIN_VALUE is less than zero. But Float.MIN_VALUE and Double.MIN_VALUE is more than zero,why?

Val SCJP2 1.2<br />====>SCJD

Corey McGlone
Ranch Hand

Joined: Dec 20, 2001
Posts: 3271

posted

0

Why they designed it this way, I'm not exactly sure, but as the API Spec for Float.MIN_VALUE states:

A constant holding the smallest positive nonzero value of type double. It is equal to the value returned by Double.longBitsToDouble(0x1L).

So, based on the API, that's exactly what Float.MIN_VALUE should return. In fact, due to the way that floats are stored, the max value and the minimum value are the same number (opposite signs, of course). For example, the range of a float is -1.7976931348623157E308 to 1.7976931348623157E308. Therefore, having two values that are really the same thing is somewhat pointless. Rather, it would be more useful to know how close and far away from zero a float can get. That's my best guess as to why this was designed in this fashion. I hope that helps, Corey

According to chapter 4.2.3. of the JLS, floating-point types in Java are "conceptually associated" with the values and operation specified in the IEEE 754 standard. This standard dictates that floating point numbers are signed magnitude. So, for a given mantissa and the exponent, by toggling the sign bit between 0 and 1 you get two "sibling" floating-points numbers, one of them positive and the other one negative, the one being the exact opposite of the other. In this signed-magnitude world, we have (among other things) a positive and negative zero (+0, -0) with one being the opposite of the other. In integer arithmetic things are not quite the same. Integers are represented in Java in a 2's-complement format. There are 2^32 integers, namely [-2^16, 2^16 - 1]. What we intuitely consider to be the opposite of -2^16 is outside the integer range, so we sort-of "decide" (led by 2's-complement arithmetic) that -2^16's opposite is -2^16 itself. There is one other integer that has itself as its opposite and it is 0. Hope this helps, Panagiotis.