approximate equality

Sorry to clog the boards with my question but I've exhausted all other avenues of research. I have a program that recursively generates the powers of a number. Base x to the nth power. The numbers that this program generates are sometimes large and when comparing them to the oracle I am using even slight differences between them are causing my if statement to fail. Its there a method by which I can test two very large or small numbers to an approximated level of equality? I've though about parsing my outputs to a string loop with a charAT() method to go number by number but I think there might be a better way.

Also, I am student and this is my first time posting in the boards so if I have placed my post in the wrong place please feel free to /flame and I'll remove it immediately.

Thank you in advance to everyone for your assistance.

// tester

public class RecursivePowerTester {

public static void main(String[] args) {

int qq=0,correct=0,x=15,n=19;

double g;

double oracle;

System.out.println("This program will solve for X^n power");

while (qq<10000)

{

x = 1 + (int)(Math.random() * 20); // random number casted to int between 1-20

n = 1 + (int)(Math.random() * 10); // random number casted to int between 1-10

RecursivePower z = new RecursivePower(x,n);

g = z.getPow(x,n);

oracle = Math.pow(x,n);

if (g==oracle)

correct++;

else

System.out.println("My recursive method " + g + " Math.pow() oracle " + oracle + " x " + x + " n " + n + "howclose" + Math.abs(oracle - g));

qq++;

}

System.out.println("Out of " + qq + " operations the oracle and the recursive method had identical values " + correct + " times");

}

}

--

public class RecursivePower {

public RecursivePower(int xx, int nn) {

x=xx;

n=nn;

}

// self calling recursive method that multiplies the base to satisfy the nuber of powers

public double getPow(int x,int n)

{

if (n ==0)

return 1;

else return x * getPow(x,n-1);

}

private int x;

private int n;

}

[2191 byte] By [MicMaca] at [2007-11-27 5:04:13]
# 1

You could cast the doubles back to int.

You could test the difference between your two values falls within some tolerance level.

c = Math.abs(a- b);

if(c <= tolerance) {

// values are essentials equal

}

P.S. why are you passing the values to your RecursivePower constructor and the getPow method?

floundera at 2007-7-12 10:22:28 > top of Java-index,Java Essentials,New To Java...
# 2
My professor feels that even very simple code should be OO. :) Turning in an assignment with less than 2 classes is a certain zero :)
MicMaca at 2007-7-12 10:22:28 > top of Java-index,Java Essentials,New To Java...
# 3

> P.S. why are you passing the values to your RecursivePower constructor and the getPow method?

> My professor feels that even very simple code should

> be OO. :) Turning in an assignment with less than 2

> classes is a certain zero :)

I think you don't understand flounder's remark. Your class contains 2 private members, which you initialise using your constructor. Afterwards you don't use them anymore since you defined parameters with the same names to your getPow() method. flounder's remark is to say: you don't need the member variables, however OO minded your professor is!

Peetzorea at 2007-7-12 10:22:28 > top of Java-index,Java Essentials,New To Java...
# 4

Yeah I totally missed the meaning of flounders response.

If I follow you I should have done the class like this instead?:

public class RecursivePower {

public RecursivePower(int xx, int nn) {

x=xx;

n=nn;

}

// self calling recursive method that multiplies the base to satisfy the nuber of powers

public double getPow()

{

if (n ==0)

return 1;

else return x * getPow(x,n-1);

}

private int x;

private int n;

}

MicMaca at 2007-7-12 10:22:28 > top of Java-index,Java Essentials,New To Java...
# 5
You should keep the parameters in your getPow method, but you don't need member variables in your RecursivePower class.
Peetzorea at 2007-7-12 10:22:29 > top of Java-index,Java Essentials,New To Java...
# 6

> You should keep the parameters in your getPow method,

> but you don't need member variables in your RecursivePower class.

That's just a choice. If you choose this, then the getPow method can be static so you don't even have to instantiate RecursivePower:double power = RecursivePower.getPow(x, n);

If the prof likes OO, another choice can be to pass the parameters in the constructor and store them in member variables. Although this seems not handy to me:RecursivePower z = new RecursivePower(x, n);

double power = z.getPow();

tom_jansena at 2007-7-12 10:22:29 > top of Java-index,Java Essentials,New To Java...
# 7
By the way your problem will probably be solved if you follow flounder's first hint. That is casting the results to int before comparing.And for as long as the x and n parameters are int, getPow's return value should be int too. That will increase the precision.
tom_jansena at 2007-7-12 10:22:29 > top of Java-index,Java Essentials,New To Java...
# 8

Using flounders changes I am getting far fewer false negatives from my if statement and that is working out pretty well. I did add a second test to it aswell.

If ((g==oracle) || Math.abs(g-oracle) < Math.abs(oracle-(oracle*.999999999999998))) //not sure how many 9's I actually put in

// not infront of my code atm but its as many as I could use before I just

// ended up with a ton of zeros

correct++;

This has given me the "fuzzy" precision that I wanted but seems alittle too easy. Would you guys consider this "close enough".

MicMaca at 2007-7-12 10:22:29 > top of Java-index,Java Essentials,New To Java...
# 9

> I wanted but seems alittle too

> easy. Would you guys consider this "close enough".

Computers can only represent so many digits of precision.

You can formalize your 999 value a bit by having it calculated (once) when the application starts up. You just put in a loop that compares previous and current value (modified) and stops when the values are the same.

jschella at 2007-7-12 10:22:29 > top of Java-index,Java Essentials,New To Java...
# 10
Ive been looking into BigInteger typed variables. Would converting all my variables to that type remove the rounding errors that I am getting with the recursive method?
MicMaca at 2007-7-12 10:22:29 > top of Java-index,Java Essentials,New To Java...
# 11

This is my code at the moment:

//tester class

public class RecursivePowerTester {

public static void main(String[] args) {

RecursivePower z = new RecursivePower();

int qq=0,correct=0,x=15,n=19;

double g;

double oracle;

System.out.println("This program will solve for X^n power");

while (qq<10000)

{

x = 1 + (int)(Math.random() * 90); // random number casted to int between 1-90

n = 1 + (int)(Math.random() * 90); // random number casted to int between 1-90

g = z.getPow(x,n);

oracle = Math.pow(x,n);

if ((g==oracle) ||(Math.abs(g-oracle) < Math.abs((oracle-(oracle*.999999999999998)) )))

correct++;

else {

System.out.println("My recursive method " + g + " Math.pow() oracle " + oracle + " x " + x + " n " + n + "howclose" + Math.abs(oracle - g));

}

qq++;

}

System.out.println("Out of " + qq + " operations the oracle and the recursive method had identical values " + correct + " times");

}

}

// recursive method class

//

public class RecursivePower {

public RecursivePower() {

}

// self calling recursive method that multiplies the base to satisfy the number of powers

public double getPow(int x,int n)

{

if (n ==0)

return 1;

else return x * getPow(x,n-1);

}

}

MicMaca at 2007-7-12 10:22:29 > top of Java-index,Java Essentials,New To Java...
# 12
The .9999999..... variable in the if statement wasn't chosen randomly - its the largest I could get the program to handle before it just started spitting zeros out for that calculation.
MicMaca at 2007-7-12 10:22:29 > top of Java-index,Java Essentials,New To Java...
# 13

> The .9999999..... variable in the if statement wasn't

> chosen randomly - its the largest I could get the

> program to handle before it just started spitting

> zeros out for that calculation.

Which is a standard way of doing a runtime calculation to determine precision.

jschella at 2007-7-12 10:22:29 > top of Java-index,Java Essentials,New To Java...