I'm failing to understand exactly what the IF statement is doing, from what I can see it is checking if the variable x is equal to the int 0. If this is true the ABSOLUTE value of the variable y is returned... this is when I lose the plot, why would the return statement then go on to include <= ESPILON? Surely this means less than or equal to the value of epsilon? if so how is that working? If it doesn't mean that then what does it mean?
(JAVA CODE)
final double EPSILON = 1E-14;
if (x == 0)
return Math.abs(y) <= EPSILON;
Floating-point math is by its nature inaccurate, so rather than testing for equivalence (which is always a bad idea), instead the developer has chosen a small number (1x10^-14 in this case) as the acceptable tolerance for proximity to zero. The return statement returns a comparison, so what this will do is take the absolute value of y, and return true if and only if it is sufficiently close to zero, where sufficiently close is defined by EPSILON.
It returns true if the absolute value of y is <= EPSILON, and false otherwise. The <= is evaluated before the return statement. This code is equivalent:
if(x == 0)
{
boolean ret = Math.abs(y) <= EPSILON;
return ret;
}
The code isn't simply read from left to right. A simpler example is
int x = 3 + 4 * 5;
After evaluating this, x is 23, not 35. The evaluation is 3 + (4*5), not (3+4)*5, because the * has a higher precedence than the +. The return statement in the original example has a very low precedence. All operators like +, -, <, >= are evaluated before it.
The entire expression
Math.abs(y) <= EPSILON
should be evaluated first, which means the function is going to return a boolean value (true/false). Having said that, if
x != 0
then I'm not sure what will get returned.
You're right that it is checking if the variable x is equal to (well, maybe int) 0. However, if this is true then it doesn't return the absolute value of y, it returns a boolean, the result of the <= operator.
It's returning a boolean value.
Epsilon is a double, holding the value 1E-14.
This is the actual IF statement
if (x==0) {
return MATH.abs(y) <= EPSILON;
}
So, what's getting returned is if the absolute value of y is less than or equals to Epsilon.
I haven't done Java in a long time but it would appear that this is actually returning a boolean (which might be implicitly cast).
I would say that if x equals 0, it returns true when the absolute value of y <= Epsilon, otherwise it returns false.
However if x doesn't equal 0 then it would return null, as no statement covers the else.
The "issue" is that this fragment relies heavyly on operator precedence (not bad per se, but sometimes it can be confusing).
Here you can find a list of all java operators with their precedence, and here for comparison the same table for C/C++
It is equivalent to this
return (Math.abs(y) <= EPSILON);
which should have been added to the code for clarity. As has been mentioned, it returns a boolean.
An alternatives would be
if (Math.abs(y) <= EPSILON)
return true;
else
return false;
Related
I ran cross this puzzler from an advanced programming course at a UK university exam.
Consider the following loop, in which i is, so far, undeclared:
while (i == i + 1) {}
Find the definition of i, that precedes this loop, such that the while loop
continues for ever.
The next question, which asked the same question for this code snippet:
while (i != i) {}
was obvious to me. Of course in this other situation it is NaN but I am really stuck on the prior one. Does this have to do with overflow? What would cause such a loop to loop for ever in Java?
First of all, since the while (i == i + 1) {} loop doesn't change the value of i, making this loop infinite is equivalent to choosing a value of i that satisfies i == i + 1.
There are many such values:
Let's start with the "exotic" ones:
double i = Double.POSITIVE_INFINITY;
or
double i = Double.NEGATIVE_INFINITY;
The reason for these values satisfying i == i + 1 is stated in JLS 15.18.2. Additive Operators (+ and -) for Numeric Types:
The sum of an infinity and a finite value is equal to the infinite operand.
This is not surprising, since adding a finite value to an infinite value should result in an infinite value.
That said, most of the values of i that satisfy i == i + 1 are simply large double (or float) values:
For example:
double i = Double.MAX_VALUE;
or
double i = 1000000000000000000.0;
or
float i = 1000000000000000000.0f;
The double and float types have limited precision, so if you take a large enough double or float value, adding 1 to it will result in the same value.
These puzzles are described in detail in the "Java Puzzlers: Traps, Pitfalls, and Corner Cases" book by Joshua Bloch and Neal Gafter.
double i = Double.POSITIVE_INFINITY;
while (i == i + 1) {}
or:
double i = 1.0e40;
while (i == i + 1) {}
both will result in an infinite loop, because adding 1 to a floating-point value that is sufficiently large will not change the value, because it doesn't "bridge the gap" to its successor1.
A note about the second puzzle (for future readers):
double i = Double.NaN;
while (i != i) {}
also results in an infinite loop, because NaN is not equal to any floating-point value, including itself 2.
1 - Java Puzzlers: Traps, Pitfalls, and Corner Cases (chapter 4 - Loopy Puzzlers).
2 - JLS ยง15.21.1
double i = Double.POSITIVE_INFINITY;
Just an idea: what about booleans?
bool i = TRUE;
Isn't this a case where i + 1 == i?
What is the smallest float value A so that (x < x + A) == true?
I tried with Float.MIN_VALUE but surprisingly(? [1]) it doesn't work (except for values of 0.)
Knowing how the IEEE 754 standard stores float values, I could just add 1 to the mantissa of the float in question, but this seams really hackish. I don't want to put byte arrays and bit operations in my code for such a trivial matter, especially with Java. In addition if I simply add 1 to the Float.floatToIntBits() and the mantissa is all 1, it will increase the exponent by 1 and set the mantissa to 0. I don't want to implements all the handling of this cases if it is not necessary.
Isn't there some sort of function (hopefully build-in) that given the float x, it returns the smallest float A such that (x < x + A) == true?
If there isn't, what would be the cleanest way to implement it?
I'm using this because of how I'm iterating over a line of vertices
// return the next vertices strictly at the left of pNewX
float otherLeftX = pOppositeToCurrentCave.leftVertexTo(pNewX);
// we add MIN_VALUE so that the next call to leftVertexTo will return the same vertex returned by leftVertexTo(pNewX)
otherLeftX += Float.MIN_VALUE;
while(otherLeftX >= 0 && pOppositeToCurrentCave.hasLeftVertexTo(otherLeftX)) {
otherLeftX = pOppositeToCurrentCave.leftVertexTo(otherLeftX);
//stuff
}
Right now because of this problem the first vertex is always skipped because the second call to leftVertexTo(otherLeftX) doesn't return the same value it returned on the first call
[1] Not so surprising. I happened to realize after I noticed the problem that since the gap between floats is relative, for whatever number != 0 the MIN_VALUE is so small that it will be truncated and (x = x + FLOAT.MIN_VALUE) == true
You can try Math.nextUp(x)
Here is the doc:
Returns the floating-point value adjacent to f in the direction of positive infinity. This method is semantically equivalent to nextAfter(f, Float.POSITIVE_INFINITY); however, a nextUp implementation may run faster than its equivalent nextAfter call.
Special Cases:
If the argument is NaN, the result is NaN.
If the argument is positive infinity, the result is positive infinity.
If the argument is zero, the result is Float.MIN_VALUE
Parameters:
f - starting floating-point value
Returns:
The adjacent floating-point value closer to positive infinity.
Is there any way to find the absolute value of a number without using the Math.abs() method in java.
If you look inside Math.abs you can probably find the best answer:
Eg, for floats:
/*
* Returns the absolute value of a {#code float} value.
* If the argument is not negative, the argument is returned.
* If the argument is negative, the negation of the argument is returned.
* Special cases:
* <ul><li>If the argument is positive zero or negative zero, the
* result is positive zero.
* <li>If the argument is infinite, the result is positive infinity.
* <li>If the argument is NaN, the result is NaN.</ul>
* In other words, the result is the same as the value of the expression:
* <p>{#code Float.intBitsToFloat(0x7fffffff & Float.floatToIntBits(a))}
*
* #param a the argument whose absolute value is to be determined
* #return the absolute value of the argument.
*/
public static float abs(float a) {
return (a <= 0.0F) ? 0.0F - a : a;
}
Yes:
abs_number = (number < 0) ? -number : number;
For integers, this works fine (except for Integer.MIN_VALUE, whose absolute value cannot be represented as an int).
For floating-point numbers, things are more subtle. For example, this method -- and all other methods posted thus far -- won't handle the negative zero correctly.
To avoid having to deal with such subtleties yourself, my advice would be to stick to Math.abs().
Like this:
if (number < 0) {
number *= -1;
}
Since Java is a statically typed language, I would expect that a abs-method which takes an int returns an int, if it expects a float returns a float, for a Double, return a Double. Maybe it could return always the boxed or unboxed type for doubles and Doubles and so on.
So you need one method per type, but now you have a new problem: For byte, short, int, long the range for negative values is 1 bigger than for positive values.
So what should be returned for the method
byte abs (byte in) {
// #todo
}
If the user calls abs on -128? You could always return the next bigger type so that the range is guaranteed to fit to all possible input values. This will lead to problems for long, where no normal bigger type exists, and make the user always cast the value down after testing - maybe a hassle.
The second option is to throw an arithmetic exception. This will prevent casting and checking the return type for situations where the input is known to be limited, such that X.MIN_VALUE can't happen. Think of MONTH, represented as int.
byte abs (byte in) throws ArithmeticException {
if (in == Byte.MIN_VALUE) throw new ArithmeticException ("abs called on Byte.MIN_VALUE");
return (in < 0) ? (byte) -in : in;
}
The "let's ignore the rare cases of MIN_VALUE" habit is not an option. First make the code work - then make it fast. If the user needs a faster, but buggy solution, he should write it himself.
The simplest solution that might work means: simple, but not too simple.
Since the code doesn't rely on state, the method can and should be made static. This allows for a quick test:
public static void main (String args []) {
System.out.println (abs(new Byte ( "7")));
System.out.println (abs(new Byte ("-7")));
System.out.println (abs((byte) 7));
System.out.println (abs((byte) -7));
System.out.println (abs(new Byte ( "127")));
try
{
System.out.println (abs(new Byte ("-128")));
}
catch (ArithmeticException ae)
{
System.out.println ("Integer: " + Math.abs (new Integer ("-128")));
}
System.out.println (abs((byte) 127));
System.out.println (abs((byte) -128));
}
I catch the first exception and let it run into the second, just for demonstration.
There is a bad habit in programming, which is that programmers care much more for fast than for correct code. What a pity!
If you're curious why there is one more negative than positive value, I have a diagram for you.
Although this shouldn't be a bottle neck as branching issues on modern processors isn't normally a problem, but in the case of integers you could go for a branch-less solution as outlined here: http://graphics.stanford.edu/~seander/bithacks.html#IntegerAbs.
(x + (x >> 31)) ^ (x >> 31);
This does fail in the obvious case of Integer.MIN_VALUE however, so this is a use at your own risk solution.
In case of the absolute value of an integer x without using Math.abs(), conditions or bit-wise operations, below could be a possible solution in Java.
(int)(((long)x*x - 1)%(double)x + 1);
Because Java treats a%b as a - a/b * b, the sign of the result will be same as "a" no matter what sign of "b" is; (x*x-1)%x will equal abs(x)-1; type casting of "long" is to prevent overflow and double allows dividing by zero.
Again, x = Integer.MIN_VALUE will cause overflow due to subtracting 1.
You can use :
abs_num = (num < 0) ? -num : num;
Here is a one-line solution that will return the absolute value of a number:
abs_number = (num < 0) ? -num : num;
-num will equal to num for Integer.MIN_VALUE as
Integer.MIN_VALUE = Integer.MIN_VALUE * -1
Lets say if N is the number for which you want to calculate the absolute value(+ve number( without sign))
if (N < 0)
{
N = (-1) * N;
}
N will now return the Absolute value
I'm doing some small program for a beginners programming course and in my program I have 2 variables which hold numbers. Anyway I need to find out which number is bigger and print the appropriate message according to it, for example I have:
int x = 5;
int y = 10;
I need to print:
"it is true that y is bigger than x";
Now the thing is that I know I can use a simple if statement but I'm not allowed to use it, now it makes me wonder, is it even possible? If so, how can I do that? How can I check which number is bigger WITHOUT doing something like:
if (x > y)
answer = true;
...
Thanks in advance.
Well you can do:
boolean answer = x > y;
The expression x > y is just an expression of type boolean. While boolean expressions are often used for conditions in if statements, loops etc, they don't have to be - simple assignment works fine too.
It sounds like you want the reverse though:
boolean answer = y > x;
Then you can use the value of answer to build the string to display...
Use the ternary operator:
System.out.println(x > y ? "It is true that x is greater than y" : "");
ternary operator "?:"
String output = (x > y)? "x is greater than y":"y is greater than x";
The ternary conditional operator that others mentioned will work. Assuming you are looking for creative ways to do this rather than practical ones, here's another method:
int x = 5;
int y = 10;
while(y > x){
System.out.println("It is true that y is bigger than x.");
return;
}
System.out.println("It is false that y is bigger than x.");
The while is just acting as a fancy if, because the return means the otherwise infinite loop will only execute at most once.
Here's another example that instead relies upon short-circuit boolean evaluation:
public static void main(String...args){
int x = 5;
int y = 10;
boolean answer = (y > x);
boolean testTrue = answer && printTrue();
boolean testFalse = testTrue || printFalse();
}
private static boolean printFalse() {
System.out.println("It is false that y is bigger than x.");
return true;
}
private static boolean printTrue() {
System.out.println("It is true that y is bigger than x.");
return true;
}
Of course you shouldn't do this in real production code, but it can be fun to think of unorthodox ways to code something and it can be helpful for exploring the language.
Your question is tagged as Java but you do not specify Java in your question. In Java there are multiple ways to get the same result that involve testing the boolean expression x > y somehow, such as the ternary operator. I would consider these equivalent to an explicit if statement.
Other possibilities:
Compute the square root of x - y. This will raise an exception if y is bigger. Catch the exception in the caller and report that y is the larger quantity. If there is no exception, report that x is the larger.
In LISP, Ruby or another language that supports the symbol type, form a list ((symbol x, x), (symbol y, y)) and sort the list. Then report the second symbol as the variable with the larger value.
If using assembly, BASIC, PL/1, etc. you can use an arithmetic expression to choose the target of a GOTO statement. Depending on whether x or y is larger, execution will resume at a different part of the code. Or use the list-sorting trick in the previous bullet to select the GOTO label.
In general, the expression ((x - y) / abs(x - y) + 1) / 2 will produce 1 if x is larger and 0 if y is larger. This result could be used to choose data, a function, etc. out of a list of two alternatives, producing conditional behavior without an if statement.
You could use recursion (but I would not recommend it)
public int compare ( int a , int b )
{
switch ( a )
{
case Integer.MIN_VALUE :
switch ( b )
{
case Integer.MIN_VALUE :
return 0 ;
default :
return -1 ;
}
default :
switch ( b )
{
case INteger.Min_VALUE :
return 1 ;
default :
return compare ( a-1 , b-1 ) ;
}
}
}
(a+b)/2 + Abs(a-b)/2 is the bigger number.
I know in some languages you can use short-circuit evaluation to construct the answer.
The expression (A && B) always evaluates to B if A is true. If A is false then B is never evaluated.
Similarly (A || B) evaluates to B if A is false. If A is true B is never evaluated.
Though I'm not 100% sure of Java, the expression you want is:
String output = ((x > y) && "it is true that X is greater than Y")
|| (((x < y) && "it is true that X is less than Y")
|| "it is true that X is equal to Y");
BigInteger bigInteger = ...;
if(bigInteger.longValue() > 0) { //original code
//bigger than 0
}
//should I change to this?
if(bigInteger.compareTo(BigInteger.valueOf(0)) == 1) {
//bigger than 0
}
I need to compare some arbitary BigInteger values. I wonder which approach is correct. Given the above code which one should be used? The original code is on the top.. I am thinking to change it to the second approach.
The first approach is wrong if you want to test if the BigInteger has a postive value: longValue just returns the low-order 64 bit which may revert the sign... So the test could fail for a positive BigInteger.
The second approach is better (see Bozhos answer for an optimization).
Another alternative: BigInteger#signum returns 1 if the value is positive:
if (bigInteger.signum() == 1) {
// bigger than 0
}
If you are using BigInteger, this assumes you need bigger numbers than long can handle. So don't use longValue(). Use compareTo. With your example it better be:
if (bigInteger.compareTo(BigInteger.ZERO) > 0) {
}
This is not a direct answer, but an important note about using compareTo().
When checking the value of compareTo(), always test for x < 0, x > 0 and x == 0.
Do not test for x == 1
From the Comparable.compareTo() javadocs:
Compares this object with the specified object for order. Returns a negative integer, zero, or a positive integer as this object is less than, equal to, or greater than the specified object.
Note:
A negative integer, not -1.
A positive integer, not 1.
True, checking for ==1 and ==-1 would work for BigInteger. This is the BigInteger.compareTo() code:
public int compareTo(BigInteger val) {
if (signum == val.signum) {
switch (signum) {
case 1:
return compareMagnitude(val);
case -1:
return val.compareMagnitude(this);
default:
return 0;
}
}
return signum > val.signum ? 1 : -1;
}
But it's still bad practice, and explicitly recommended against in the JavaDocs:
Compares this BigInteger with the specified BigInteger. This method is provided in preference to individual methods for each of the six boolean comparison operators (<, ==, >, >=, !=, <=). The suggested idiom for performing these comparisons is: (x.compareTo(y) <op> 0), where <op> is one of the six comparison operators.