How to calculate exact value of a trig function?
I am writing a "triangle solver" app for Android, and I was wondering if it would be possible to implement exact values for trig ratios and radian measures. For example, 90 degrees would be output as "pi / 2" instead of 1.57079632679...
I know that in order to get the exact value for a radian measure, I would divide it by pi and convert it to a fraction. I don't know how I would convert开发者_如何学Python the decimal to a fraction.
like this:
int decimal = angleMeasure / Math.PI;
someMethodToTurnItIntoAFraction(decimal);
I don't even know where to begin with the trig ratios.
You need to take the number and divide it by each of the "special" numbers: pi,e, sqrt(2), sqrt(3), sqrt(5). After each division, determine if the resulting number is close to an exact fraction. To do the last part, use the continued fraction algorithm to find good approximations to the number. There are criteria you can use in the continued fraction expansion to determine if the approximation is nearly exact. If you get a nice fraction with small numbers that is nearly exact then that's your answer - the fraction times the special number that was divided by at the beginning. Oh and consider "1" as a divisor so simple fractions come out too.
Been there, done that, works well. I don't recall the algorithm for getting approximate fractions without storing and collapsing the entire continued fraction, but it's been linked here on SO recently.
What you're talking about is using Pi as a concept instead of a number. I'd do something like this:
class Fraction {
public int num;
public int den;
public Fraction(int n,int d) {
num=n;
den=d;
}
public Fraction() {
num=1;
den=1;
public double decValue() {
return ((double)num)/((double)den);
}
}
yadda, yadda....
public static Fraction someMethod(double decVal) {
Fraction f=new Fraction(1,1);
double howclose=0.0000001; //tiny amount of error allowed
while(abs((f.decValue()*Math.PI)-decVal)>howclose) {
if(f.decValue()*Math.PI>decVal) {
f.den++;
}
else {
f.num++;
}
}
return f;
}
Basically, work on getting the fraction closer and closer to the expected answer (decVal). The fraction will be in the form of:
num*PI
------
den
Basically, multiply the fraction that's in the result by Pi, and it should be very close to decVal.
Nobody stops you from using fractions as they come. Integer, Double, etc. are just objects, that can be used with 4 operations: +, -, *, /. You can use some kind of object Fraction, which will also perform these operations (not like operators, but like plain methods - consider BigInteger for example of such use), but do it in its own manner. For some aspects of creating new number types see SICP, and for implementation in Java see these notes.
EDIT
What I mean is not creating your someMethodToTurnItIntoAFraction
, but using natural fractions themselves. I.e. your code will look like this:
Fraction f = new Fraction(angleMeasure, Fraction.PI);
System.out.println(f.getNum() + "/" + f.getDen());
It will take more time, but will keep your numbers precise.
IIRC, chips compute trigonometrical functions using Taylor's polynom, which is a row of additions of fractions. So you could implement that computation and keep it in fractions. Will be slow, of course.
http://en.wikipedia.org/wiki/Taylor_series
精彩评论