Simplify a long boolean expression - java

Im pretty new to this plattform and well I have a trouble regarding boolean expression in my CS-class. I have to simplifly this boolean expression and have no clue how to do this.
double x ;
double y ;
boolean b = ( (y < -x) ^ (5 * x >= y) ) && ( (x < -y) != (x >= y * 0.2) )

Assuming pure math, y < -x is equivalent to x < -y, 5 * x >= y is equivalent to x >= y * 0.2 and whateverBoolean1 ^ whateverBoolean2 is equivalent to whateverBoolean1 != whateverBoolean2. Hence you can omit any side of && operator.
I am neglecting freaks of floating point arithmetics (0.2 is not precise number so some counterexample that original and simplified expression are not equivalent could be perhaps found after some effort.)

Related

How to Correctly Round a Square Root Function?

I am currently working on a Java math library which will include a variety of correctly rounded functions (i.e. sqrt, cbrt, exp, sin, gamma, and ln). I have already used the Babylonian method to write a square root algorithm that is correct to within 1 ulp of the correct answer. However, I cannot figure out how to properly calculate which way the number should be rounded to represent the best possible approximation to the actual square root of the input. Answers containing principles which can be extended to other functions would be preferred, but I have heard that sqrt is a simpler case than many transcendental functions, and specialized solutions would also be much appreciated.
Also, here is a cleaned-up version of my code as of this question's original submission:
public static double sqrt(double x) {
long bits = Double.doubleToLongBits(x);
// NaN and non-zero negatives:
if (Double.isNaN(x) || x < 0) return Double.NaN;
// +-0 and 1:
if (x == 0d || x == 1d) return x;
// Halving the exponent to come up with a good initial guess:
long exp = bits << 1;
exp = (exp - 0x7fe0000000000000L >> 1) + 0x7fe0000000000000L >>> 1 & 0x7ff0000000000000L;
double guess = Double.longBitsToDouble(bits & 0x800fffffffffffffL | exp);
double nextUp, nextDown, guessSq, nextUpSq, nextDownSq;
// Main loop:
while (true) {
guessSq = guess * guess;
if (guessSq == x) return guess;
nextUp = Math.nextUp(guess);
nextUpSq = nextUp * nextUp;
if (nextUpSq == x) return nextUp;
if (guessSq < x && x < nextUpSq) {
double z = x / nextUp;
if (z * nextUp > x) z = Math.nextDown(z);
return z < nextUp ? nextUp : guess;
}
nextDown = Math.nextDown(guess);
nextDownSq = nextDown * nextDown;
if (nextDownSq == x) return nextDown;
if (nextDownSq < x && x < guessSq) {
double z = x / guess;
if (z * guess > x) z = Math.nextDown(z);
return z < guess ? guess : nextDown;
}
// Babylonian method:
guess = 0.5 * (guess + x / guess);
}
}
As you can see, I was using division as a test. However, I believe that requires the division to round towards 0, which obviously doesn't happen in Java.
By the Taylor theorem, the square root function is locally approximated by a linear function, of slope 1/2√x, which is positive. So you can relate the error to the error in the square, x - (√x)², where √x is understood to be the approximate root. Then you round in the direction that minimizes this error.
Anyway, the computation of x - (√x)² is subjected to catastrophic cancellation and you may need extended accuracy to compute it reliably. Not sure the benefit is worth the effort.

how to convert a python expression to a java expression?

I have the following expression in python:
if 0.85 < 0.81 / 0.83 < 1.15 :
//do something
When I put this in python there is no problem and it returns a boolean (true) but I don't understand what '/' is? because it looks like your dividing two booleans. What does this expression evaluation to in java?
In java,
if (0.85 < 0.81 / 0.83 && 0.81 / 0.83 < 1.15) {
//do something
}
// A better solution as mentioned by #Makoto
float f = 0.81/0.83
if (0.85<f && f< 1.15) {
//do something
}
In Python, all comparison operations have the same priority. It can be chained arbitrarily, e.g., x < y < z is equivalent to x < y and y < z. Refer to Python documentation: Expressions for the detailed description.
you might want to use and(&&) to get a True :
if (0.85 < 0.81 / 0.83 && 0.81 / 0.83 < 1.15) {
//do something
}
Going to the docs, the answer to your question is literally spelled out in these two sections (both on the same page):
https://docs.python.org/3/reference/expressions.html#operator-precedence
https://docs.python.org/3/reference/expressions.html#comparisons
The first section gives a table that states that / has higher precedence than <, so your expression is effectively 0.85 < (0.81 / 0.83) < 1.15, or 0.85 < 0.9759036144578315 < 1.15.
The second section states:
Comparisons can be chained arbitrarily, e.g., x < y <= z is equivalent to x < y and y <= z, except that y is evaluated only once (but in both cases z is not evaluated at all when x < y is found to be false).
This means that your statement translates exactly as
double x = 0.81 / 0.83;
if(0.85 < x && x < 1.15) {
// ...
}
The key here is that with comparison chaining, each expression is only evaluated once. In this case that means computing the division only once. Of course the Java compiler would probably have optimized that out for you anyway.

Hard time finding an error in my code

I have some problems with my java code here. When I try to compile I get the error:
"bad operand types for binary operator '&&'" for the if statement
which I usually get when I made an error in the boolean logic. For the past half hour I've tried to find the mistake in my code but I'm not able to find it.
Any pointers?
code below
public String toString(){
double x1 = this.ecke1.getX();
double y1 = this.ecke1.getY();
double x2 = this.ecke2.getX();
double y2 = this.ecke2.getY();
double[] Y = {y1,y2,0};
double[] X = {x1,x2,0};
for (int y = 0; y <= Utils.max(y1,y2,0); y++)
for(int x = 0; x <= Utils.max(x1,x2,0); x++)
if ( ((x=0) && (y=0) ) || ( ( (y/x) <= (Utils.min(X)/Utils.max(Y)) ) && ( (y/x) >= (Utils.min(Y)/Utils.max(X)) ) && ( (y/x) <= ((Utils.max(Y)-Utils.min(Y)) / (Utils.min(X) - Utils.max(X))) ) ) )
System.out.print("#");
else system.out.print("-");
}
Change
(x=0) && (y=0)
to
(x==0) && (y==0)
x=0 is an assignment, so it doesn't evaluate to a boolean. x==0 is a comparison, and returns a boolean.
Use double equal to sign(==) instead of single(=)
if (((x==0) && (y==0) )...)
You use single equal sign for assignment and double for comparison.
= is an assignment operator while == is a comparison operator.
So you need to use x == 0 && y == 0.

float within 3 of each other if else statement?

Is there a way in Java to make it so that if X is within 3 of Y that it will be true (need a if statement).
I tried:
import java.util.*;
import java.io.*;
public class e4 {
public static void main (String arg[]) {
if ( ( (x - 3) <= y ) || ( (x - 3) <= y) || (x >= (y -3) ) || (x >= (y -3) ))
{
System.out.println("Your are within 3 of each other!");
}
else
{
System.out.println("Your NOT within 3 of each other.");
}
} //end main
} //end class
Thanks a lot for any help!
Use something simpler:
if (Math.abs(x - y) < 3.0) {
// within 3
}
You don't need Math.abs. Do this.
if ( x >= y - 3 && x <= y + 3 )
Here's a case where Math.abs gives you a wrong answer, because the subtraction loses the small quantity from the small float. If accuracy is important to you, you should avoid using Math.abs for this reason.
Note that it's possible to concoct an example where a similar thing happens with MY solution; but there are fewer such examples, and they only happen where the "ranges" represented by x and y contain parts that differ by more than 3 and parts that differ by less than 3.
float x = - 0.2500001f;
float y = 2.75f;
System.out.println( x >= y - 3 && x <= y + 3 ); // Prints false (correct)
System.out.println( Math.abs(x-y) <= 3.0); // Prints true (wrong)

Recursion and multiplication

Is this possible guys? This is homework I have, and my teacher obviously believes it is, but it seems to me that it's impossible not to use addition or multiplication outside of the short-multiplication method.
Write (and provide a tester for) a recursive algorithm:
int multiply(int x, int y)
to multiply two positive integers together without using the *
operator. Do not just add x to itself y times!!!
(Hint: Write a recursive method that will multiply an integer by a
value in the range 0 .. 10. Then write a second recursive method to
implement the multiplication algorithm you learned to multiply
multi-digit numbers in elementary school.)
My issue is that once you break down any multi digit number and starting adding those together you have to use multiplication of numbers greater than 10, i.e 22 * 6 is 2 * 6 + 20 * 6 ... so am I totally missing something?
EDIT
I guess I should have added this is the code I have,
public int mult(int x, int y){
return x == 0 ? 0 : (mult(x-1, y) + y);
}
which is perfect, but as far as I understand the instructions, that's breaking do not just add x to itself y times. I personally believe it isn't, but my teacher hasn't been very clear, and I'd like to know if there's some other way that I havn't thought of, sorry for the confusion.
Yes, it's possible. Yes, I think you're missing something. Try writing down the steps you'd follow to manually multiply two numbers, the way you learned in elementary school.
Then turn those steps into code.
My interpretation of the assignment is that the teacher would like the student to implement a recursive algorithm to perform Grid method multiplication (the kind we learn in elementary school).
For example, multiplying 34 x 13 would be done like so...
34
* 13
====
12
90
40
+300
====
442
I didn't have easy access to a Java development environment, so I wrote the code in C# but the algorithm should be simple enough to convert into Java.
public int Multiply(int x, int y)
{
if (x < 0) throw new ArgumentException("must be positive integer", "x");
if (y < 0) throw new ArgumentException("must be positive integer", "y");
if (x == 0 || y == 0) return 0; // obvious quick-exit condition
// integer division
int xDivBy10 = x / 10;
int yDivBy10 = y / 10;
bool xIsSingleDigit = xDivBy10 == 0;
bool yIsSingleDigit = yDivBy10 == 0;
// base case
if (xIsSingleDigit && yIsSingleDigit)
{
return MultiplySingleDigits(x, y);
}
// otherwise, use grid multiplication recursively
// http://en.wikipedia.org/wiki/Grid_method_multiplication
if (xIsSingleDigit) // y must not be a single digit
{
return (Multiply(x, yDivBy10) * 10) + Multiply(x, y % 10);
}
if (yIsSingleDigit) // x must not be a single digit
{
return (Multiply(xDivBy10, y) * 10) + Multiply(x % 10, y);
}
// else - x and y are both numbers which are not single digits
return (Multiply(x, yDivBy10) * 10) + Multiply(x, y % 10); // the same code as the "if (xIsSingleDigit)" case
}
// technically, this algorith can multiply any positive integers
// but I have restricted it to only single digits as per the assignment's requirements/hint
private int MultiplySingleDigits(int x, int y)
{
if (x < 0 || x > 9) throw new ArgumentException("must be in range 0 - 9 (inclusive)", "x");
if (y < 0 || y > 9) throw new ArgumentException("must be in range 0 - 9 (inclusive)", "y");
if (x == 0 || y == 0) return 0; // base case
return x + MultiplySingleDigits(x, y - 1);
}
NOTES:
This approach still uses the * operator but not for actually multiplying x and y, it is used to increase other sub-products by multiples of 10
Many parts of this code could be simplified/refactored but I specifically left them expanded to make the steps more obvious
Of course you can do it.
First of all, think about the condition. If some number is 0, then the result is? Right.. zero.
So.. You'll have if x is zero or y is zero return 0
Now.. saying X * Y is like saying "X, Y times", which is like writing: X + .... + X (Y times).
So, you'll have something like:
x + multiply(x, y - 1);
You'll have to consider the case in which one of the numbers is negative (But if you understand the basic, I believe you can easily do it).
This solution will work for both when y>=0 and y<0
public int multiply(final int x, final int y) {
if (y != 0 && x != 0) {
if (y > 0) {
return multiply(x, y - 1) + x;
} else {
return multiply(x, y + 1) - x;
}
}
return 0;
}
Easily possible.
int multiply(int x, int y) {
if(y == 0) {
return 0;
}
return x + multiply(x, y - 1);
}
The above fails to take into account the case where y is negative, but you wouldn't want me to do all your work for you . . .
static int Multiply(int x, int y)
{
if (y > 0 && x > 0)
return (x + Multiply(x, y - 1));
if (y < 0 && x > 0)
return -Multiply(x, -y);
if (x < 0 && y > 0)
return -Multiply(-x, y);
if (x < 0 && y < 0)
return Multiply(-x, -y);
return 0;
}

Categories

Resources