Java math equation solver [not normal equations] - java

I need a method in java which returns a solve for an equation this equation without code is like this :
get a number(Z)
and an angle(C) in radians
then find the value of X which is the solution for this equation:
a = Integer( z*cos(c) ) // temp must be integer
//now we have the value of a
// we put it in b
b = a
//now we look for the value of x that solves this equation
b =? Integer( X/cos(C) ) // X also must be integer
X = ?? // we must get X the solves the equation above
Example: consider
Z = 15
C = 140 // full angles will be casted ..it will be rooted to ~-0.0629*PI
temp = Integer( 15*cos(140) // -2.96 )
temp <-- -2 //after parsing to integer
-2 = Integer ( X )/cos(140)
what is X ?
I tried to implement this method in java but most of the times it stuck finding a result
this code doesn't find a direct solution like i want it tests numbers till it gets it but in many of times it can't find a result and keeps looping to the infinity . Also it is so slow in finding the result and i call that function more than 500,000 times in the program
int Rounding(int z, int c){
int offset = 20 ;
int x;
int test = (int) ( z*Math.cos(c) - offset );
int solution;
while(true){
solution = (int) ( test/Math.cos(c) );
if(solution == z){
x = solution;
break;
}else{
test++;
}
/*
if(solution > z){
offset ++;
solution = (int) ( z*Math.cos(c) - offset );
}
*/
}
return x;
}
/*Note : the function will return x only when it solves this : */
int returned_Z = (int) ( x/Math.cos(c) )
// returned_Z must be equal to z
After that that variable x will be stored in a file ...
then when the file opens this variable x will be returned to z with this function :
int returning(int x, int c){
int z = (int) ( x/Math.cos(c) );
return z;
}

From your posting, we have
temp = Integer( 15*cos(140) // -2.96 )
Find X such that
temp = Integer ( X/cos(140) )
We can solve this for X without the integer conversions.
X = 15 / cos^2(140)
or, in general
X = Z / cos^2(C)
This will give you an exact solution for X; you may apply the integer intermediate requirement if needed for some other purpose.
Update per OP comment
You have a defined mathematical relationships between X, temp, and Z. Truncating the intermediate result breaks some of that relationship. In short, if you restrict X to integers, you cannot guarantee that you get exactly Z when you apply the inverse operations.
In particular, you have a transcendental function cos; you cannot dictate that it will be the ratio of your integers temp and X or X and Z. There do exist point solutions for cos that are known rational numbers, but very few.
If I misunderstand the problem -- I realize that we have some translation problem -- then please update your question to specify the correct problem.

Actually the eqn has infinite number of solutions. Say temp = 2. And you write:
2 = Integer ( ( X )/cos(140) )
If we take Integer() for all real numbers in the range 2.0 <= num < 3.0, it results in 2. That's why infinite number of solutions possible. For example, if we take 2.5 from the range:
2 = Integer (2.5) is true
so we can write,
x / cos(140) = 2.5
=> x = 2.5 * cos(140)
= −1.915111108
If we take another 2.3 from the range:
x = −1.761902219
Since there infinite number of real numbers in the range 2.0 <= num < 3.0, the number of solutions is infinite too.
So you can't just expect a single solution for x. If you do, then use:
int Rounding(int z, int c){
int test = ( z*Math.cos(c) );
int x = (int) ( test*Math.cos(c) );
return x;
}
This will give you a correct answer. But as I said before, there are infinite number of solutions for x.

Related

Why are my cos(x) outputs out of bound 1 and -1?

My task is to implement the cos(x) function withou using Math. library and with the taylor polynom, my code looks like this:
public class Cosinus {
public static void main(String[] args) {
/*if(args.length == 0){
System.out.println("ERROR: Geben Sie ein Argument für x ein!");
return;
}*/
double x = 5;
double summand1 = (x*x) / 2;
double summand2 = (x*x*x*x) / (2*3*4);
double summand3 = (x*x*x*x*x*x) / (2*3*4*5*6);
double summand4 = (x*x*x*x*x*x*x*x) / (2*3*4*5*6*7*8);
double summand5 = (x*x*x*x*x*x*x*x*x*x) / (2*3*4*5*6*7*8*9*10);
double summand6 = (x*x*x*x*x*x*x*x*x*x*x*x) / (2*3*4*5*6*7*8*9*10*11*12);
double summand7 = (x*x*x*x*x*x*x*x*x*x*x*x*x*x) / (2*3*4*5*6*7*8*9*10*11*12*13*14);
//double summand8 = (x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x) / (2*3*4*5*6*7*8*9*10*11*12*13*14*15*16);
//double summand9 = (x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x) / (2*3*4*5*6*7*8*9*10*11*12*13*14*15*16*17*18);
//double summand10 = (x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x) / (2*3*4*5*6*7*8*9*10*11*12*13*14*15*16*17*18*19*20);
double cosinusFunktion = (((((((1 - summand1) + summand2) - summand3) + summand4) - summand5) + summand6) - summand7);
System.out.println(cosinusFunktion);
}
}
For x = 1, 2, 3, and 4 Y is between 1 and -1
but with x = 5 it goes too -4 and if the x are even getting bigger this continues too 1287918274.
I cant solve this task but tthe task says it is enough to implement this funktion iwth the taylor polynom and the first 11 summand. I tried this too, but then even with x = 1 the bounds are broken. How can i solve this, so x = 42.5 is in bound of -1 and 1?
Tried more summands to make the result more excact, but the bounds get broken even more.
tried implement the periodicity of x-2*PI, but I dont know where to put it and results get messed up eeven more.
you are getting an integer overflow for the factorial in the summand7 line
as a simple fix you can change the line to:
double summand7 = (x*x*x*x*x*x*x*x*x*x*x*x*x*x) / ((double) 2*3*4*5*6*7*8*9*10*11*12*13*14);
The Taylor expansion will always blow up for larger inputs. However, since:
sin(x) = sin(x + n*2*pi) // for any integer n
You can simply pre-process you input with a modulus function to prevent your output from blowing up.
I can't test compile right now, but if memory serves, you would add one of the following lines prior to computing your first summand:
x = x%(Math.PI*2)
Or, if you can't use Math
x = x%((double)3.14159265358979323846*2)

Calculating modulo inverse in java

I was trying to figure out a way to calculate modulo inverse using java so I wrote this function to do it:
public static int privatekey(int primeprod, int e, int lambda)
{
Random random = new Random();
float d = 0;
//extended euler's theorem is
//d = (1 + x*lambda) / e
//d is smaller than primeprod
while(true)
{
int d = random.nextInt(200) + 1;
System.out.println("seed: "+x);
var = (1 + (x*lambda)) / e;
System.out.println("var: "+d);
if(isInteger(d) && d < primeprod)
{
break;
}
}
int finalvar = (int)d;
return finalvar;
}
I felt that it was going wrong so I reversed euclidean theorem extension I used above as follows
1 + x.lambda
------------- = d (this one is the equation to find out d when x is any integer)
e
de = 1 + x.lambda
de - 1 = x.lambda
de - 1
------- = x (this one is to check whether the value obtained by the above equation is true or not by checking if x is the same value we had chosen for our calculation in the first place)
lambda
After doing this check I found that the value of x I obtained in the reversed equation I had solved to check for mistakes is not equal but approximate to the original random value which I had generated.
For example taking these values:
e = 327
lambda = 484
x = 76
We get d as 112.0
later We reverse The equation to find the value of x to confirm
we get:
x = 75.667355372 (Which is approximate to the original value)
I wasn't able to figure out where it was going wrong.
To look at the full program please visit this link.
Please tell me If I have done something wrong here.
Thank You in advance!
Alright I got an answer to this problem.
The Issue was I was performing arithmetic operations on integer so the value I got as result was an integer.
Instead of using integer I later used Double to do the same operation and I resolved the issue.
public static int privatekey(Double primeprod, Double e, Double lambda)
{
Random random = new Random();
float d = 0;
//extended euler's theorem is
//d = (1 + x*lambda) / e
//d is smaller than primeprod
while(true)
{
int d = random.nextInt(200) + 1;
System.out.println("seed: "+x);
var = (1 + (x*lambda)) / e;
System.out.println("var: "+d);
if(isInteger(d) && d < primeprod)
{
break;
}
}
int finalvar = (int)d;
return finalvar;
}
This resolved the issue.

Why does reversing an operation allow overflow handling?

A leetcode problem (https://leetcode.com/problems/reverse-integer/description/) asks to reverse an integer, which is simple enough, but wants the user to return 0 if there is any overflow. Doing this with long is also simple, as you can check if it's greater than INTEGER.MAX_INT or MIN_INT in java. But if only 32 bit ints are allowed, how can this be accomplished?
The following solution is shown:
public int reverse(int x)
{
int result = 0;
while (x != 0)
{
int tail = x % 10;
int newResult = result * 10 + tail;
if ((newResult - tail) / 10 != result)
{ return 0; }
result = newResult;
x = x / 10;
}
return result;
}
I'm confused why this works. Why does "reversing" the operation, and comparing it to the previous result successfuly check for overflow?
If you started with x, then said:
x2 = (x*10) + b, wouldn't (x2-b)/10 always equal x? Since a positive overflow always loops around to the min value, and a negative overflow always loops around to the max value. How does this check for overflow? I would love any clarifications on this.
If you started with x, then said: x2 = (x*10) + b, wouldn't (x2-b)/10 always equal x?
No. Your intuition about "looping" is correct for addition and subtraction - it's like moving back and forth on a clock face around 12 o'clock.
However, this doesn't apply to multiplication, as this example demonstrates:
int x = 2_000_000_000;
int y = x * 10;
int z = y / 10;
System.out.println(x); // 2000000000
System.out.println(z); // -147483648
Live demo.
So to answer the top-level question:
Why does "reversing" the operation, and comparing it to the previous result successfully check for overflow?
Because when overflow occurs, "reversing" this sequence of operations won't get you back to the input value.

While statement trouble Java

While I was working on a program that simulates a dice, I encountered a problem.
This is the code I wrote (I know it is not good programing at all but I'm learning). It works and of course I know that there is unnesecary parts in it, but is not the problem.
double x ;
String z ;
x = Math.random() ;
z = Double.toString(x) ;
z = z.substring(2, 3) ;
while (x>6 || x<1) {
x =Math.random() ;
z = Double.toString(x);
z = z.substring(2, 3) ;
x = Integer.parseInt(z );
}
z = Double.toString(x );
z = z.substring(0, 1) ;
JOptionPane.showMessageDialog(null, "Antal prickar: "+z);
The problem is that saw that I erlier had an if statement in the while loop and it worked a couple of weeks ago and now when I rewrote the code it is not working.
double x ;
String z ;
x = Math.random() ;
z = Double.toString(x) ;
z = z.substring(2, 3) ;
while (x>6 || x<1) {
if (x>6) {
x =Math.random() ;
z = Double.toString(x);
z = z.substring(2, 3) ;
x = Integer.parseInt(z );
}
}
z = Double.toString(x );
z = z.substring(0, 1) ;
JOptionPane.showMessageDialog(null, "Antal prickar: "+z);
Can anyone explain why it is not working because I should be able to put the if statement inside the while loop without it giving me errors right?
Assuming your previous code was working (and skipping comments on style etc.) the main problem seems to be the added if-statement.
Consider the case where x = 0:
while( x > 6 || x < 1) will run since the condition is satisfied (x is smaller than 1).
if(x > 6) is not satisfied though (x is not greater than 6) and thus x will never be updated, resulting in an endless loop.
Btw, I'd not use Math.random() but rather create a new instance of Random and then call nextInt(6) + 1 to get a random integer between 1 and 6 (both inclusive):
Random rand = new Random(); //you might want to store this elsewhere and reuse the instance
int dice = rand.nextInt(6) + 1; //done, random integer between 1 and 6
It seems you are using java.lang.Math.random() to generate a number between and 1 and 6. As that random() call returns a value normalized in the 0.0 to 1.0 interval, you choose the first decimal as your candidate value and in the case it is off limits, you repeat the random() call to get a new candidate number.
In the second snippet you sent post (the one you say is not working), the formatting shows that the while loop only contains the if statement, and this statement will only do something if x > 6, but x will never be over 6 as the value is between 0 and 1.
You might be missing this line in the first block before the while loop:
x = Integer.parseInt(z );
And the if condition within the loop shall be removed.
Edit: to produce a random value between 1 and 6 the simpliest piece of code I can thing about is:
new java.util.Random().nextInt(6) + 1

Mapping (x,y) to single number value

I want a function to map the (x,y) value to a single number value and corresponding reverse mapping in Java.
For example (2,34) should map to some value 100 and if we have 100 we should be able to find (2,34).
Well, if you have a maximum value for one of them, then yes. Say y is limited to 0...9999, then could can do:
int num = x * 10000 + y;
(assuming of course that the result will fit in the type - you can possibly upgrade to a wider type like long if necessary). Then, to go back:
int x = num / 10000;
int y = num % 10000;
If you've got an upper limit (say 100 is the higher for x in (x,y)), then you could associate any n to a pair of values (x,y) with this function: n = x * 100 + y.
If you don't have any limit things get more difficult. A way to associate a number belonging to R, to a number of R^2 is that of enumerating diagonals. Look at this example, it's a matrix where the (x,y) cell contains the n associated to it:
1 2 4 7 11 ..
3 5 8 12 ..
6 9 13 ..
10 ..
..
Remember, primitive numbers are just a bunch of raw bits. If your numbers are 32-bit integers (int), you could conveniently pack two of them into one 64-bit integer (long). Something like this:
int a = 3;
int b = 4;
long c = ((long) a) << 16 | b;
...
a = (int) (c >> 16);
b = (int) (c & 0xffff);
You should take a look at HashMap.
Something like HashMap<Integer, List<Integer>> seems to work well for your case.
public class hash {
public static void main(String args[]) throws IOException
{
HashMap<List<Integer>,List<Integer>> g=new HashMap<List<Integer>,List<Integer>>();
List<Integer> xys=new ArrayList<Integer>();
List<Integer> ss=new ArrayList<Integer>();
System.out.println("Enter the coordinates in (x,y)");
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
System.out.println("x");
int n1=Integer.parseInt(reader.readLine());
System.out.println("y");
int n2=Integer.parseInt(reader.readLine());
xys.add(n1);
xys.add(n2);
int d=(int)(Math.pow(xys.get(0),xys.get(1)));
ss.add(d);
g.put(xys,ss);
g.put(ss,xys);
List<Integer> r= g.get(ss);
List<Integer> r1=g.get(xys);
System.out.print("Hash for the value (x,y) mapping");
System.out.print(r1);
System.out.print("Hash for the value N, reverse mapping");
System.out.println(r);
}
}
You can keep them as a String.
String a = "(2,34)";
String b = "100";
Map<String, String> m = new HashMap<String, String>();
m.put(a, b);
m.put(b, a);
/*print*/
System.out.println(m.get(a));
System.out.println(m.get(b));
What is the background for this requirement?
If the range of x, y values is unlimited, then there is no way to do this in a unique way (so that you can always reverse the process).
If the range of the numbers is limited, then you could do the following: Suppose that x and y are int values both in the range 0 to 99. Then you calculate the result by: z = 100 * x + y. The reverse would be: x = z / 100 and y = z % 100.
An alternative strategy based on paxdiablo's answer is to use the decimal point, so you would put the x component before the decimal place and the y component after it.
This can entail some messy string handling, but doesn't have the limitation that you need to be able to bound one of your coordinates.

Categories

Resources