Как рассчитать точное значение функции триггера? - PullRequest
2 голосов
/ 09 февраля 2011

Я пишу приложение «Решатель треугольников» для Android, и мне было интересно, можно ли реализовать точные значения для коэффициентов триггера и радиана. Например, 90 градусов будут выводиться как «пи / 2» вместо 1,57079632679 ...

Я знаю, что для получения точного значения радиана, я бы разделил его на пи и преобразовал бы в дробь. Я не знаю, как бы преобразовать десятичную дробь в дробную.

как это:

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

Я даже не знаю, с чего начать с триггеров.

Ответы [ 4 ]

1 голос
/ 10 февраля 2011

Вам нужно взять число и разделить его на каждое из «специальных» чисел: pi, e, sqrt (2), sqrt (3), sqrt (5).После каждого деления определите, является ли полученное число близким к точной дроби.Чтобы выполнить последнюю часть, используйте алгоритм продолжения дроби, чтобы найти хорошее приближение к числу.Существуют критерии, которые можно использовать в продолжении расширения дроби, чтобы определить, является ли приближение почти точным.Если вы получите хорошую дробь с небольшими числами, которая почти точна, то это ваш ответ - дробь умноженная на специальное число, на которое делилось в начале.Да, и рассмотрите "1" как делитель, так что простые дроби тоже выходят.

Был там, сделал это, работает хорошо.Я не помню алгоритм получения приблизительных дробей без сохранения и свертывания всей продолженной дроби, но он недавно был связан здесь на SO.

0 голосов
/ 10 февраля 2011

То, о чем вы говорите, использует Пи как концепцию вместо числа. Я бы сделал что-то вроде этого:

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

Ядда, Ядда ....

 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, и она должна быть очень близко к декаВалу.

0 голосов
/ 10 февраля 2011

IIRC, чипы вычисляют тригонометрические функции, используя полином Тейлора, который представляет собой ряд сложений дробей.Таким образом, вы можете реализовать это вычисление и хранить его в дробях.Будет медленно, конечно.

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

0 голосов
/ 10 февраля 2011

Никто не мешает вам использовать дроби по мере их поступления.Integer, Double и т. Д. - это просто объекты, которые можно использовать с 4 операциями: +, -, *, /.Вы можете использовать некоторый объект Fraction , который также будет выполнять эти операции (не как операторы, а как простые методы - рассмотрим BigInteger в качестве примера такого использования), но сделайте это по-своему.Для некоторых аспектов создания новых типов чисел смотрите SICP , а для реализации в Java смотрите эти примечания.

EDIT

Я имею в виду не создание вашей someMethodToTurnItIntoAFraction, а использование самих натуральных дробей.Т.е. ваш код будет выглядеть так:

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

Это займет больше времени, но сохранит ваши цифры точными.

...