如何计算trig函数的精确值?

时间:2011-02-09 20:46:41

标签: java math precision trigonometry pi

我正在为Android编写一个“三角形求解器”应用程序,我想知道是否可以实现触发比率和弧度测量的精确值。例如,90度将输出为“pi / 2”而不是1.57079632679 ...

我知道为了获得弧度测量的精确值,我会将其除以pi并将其转换为分数。我不知道如何将小数转换为分数。

像这样:

int decimal = angleMeasure / Math.PI;
someMethodToTurnItIntoAFraction(decimal);

我甚至不知道从哪里开始使用触发比率。

4 个答案:

答案 0 :(得分:1)

你需要取数字并除以每个“特殊”数字:pi,e,sqrt(2),sqrt(3),sqrt(5)。在每次除法后,确定结果数是否接近精确分数。要完成最后一部分,请使用连续分数算法来查找数字的良好近似值。您可以在连续分数展开中使用标准来确定近似是否几乎精确。如果你得到一个很小的数字几乎精确的分数那么这就是你的答案 - 分数乘以开头时除以的特殊数字。哦,并将“1”视为除数,这样简单的分数也会出现。

在那里,做到了,效果很好。我不记得在没有存储和折叠整个连续分数的情况下得到近似分数的算法,但它最近在SO上链接了。

答案 1 :(得分:0)

没有人阻止你使用分数。 Integer,Double等只是对象,可以用于4个操作:+, - ,*,/。你可以使用某种对象分数,它也会执行这些操作(不像运算符,但是像普通方法一样 - 考虑使用BigInteger作为这种用法的例子),但是以自己的方式进行。有关创建新数字类型的某些方面,请参阅SICP,有关使用Java实现,请参阅these注释。

修改

我的意思是不是创建你的someMethodToTurnItIntoAFraction,而是自己使用自然分数。即你的代码看起来像这样:

Fraction f = new Fraction(angleMeasure, Fraction.PI); 
System.out.println(f.getNum() + "/" + f.getDen());

需要更多时间,但会保持您的数字准确。

答案 2 :(得分:0)

IIRC,芯片使用泰勒多项式计算三角函数,这是一系列分数的加法。因此,您可以实现该计算并将其保持在分数中。当然会很慢。

http://en.wikipedia.org/wiki/Taylor_series

答案 3 :(得分:0)

你所说的是使用Pi作为概念而不是数字。我会做这样的事情:

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;
}

基本上,努力让分数更接近预期答案(decVal)。分数将采用以下形式:

num*PI
------
den

基本上,将结果中的分数乘以Pi,它应该非常接近decVal。