, так как вы также считаете

аюсь сделать некоторый анализ над простымFraction класс, и я хочу, чтобы некоторые данные, чтобы сравнить этот тип сdoubles.

Проблема

Точно знаю, я ищу хороший способ получить плотность фракций между 2 числами. Дроби в основном 2 целых числа (например,pair< long, long>), а плотность междуs а такжеt это количество представимых чисел в этом диапазоне. И это должно быть точное или очень хорошее приближение, выполненное в O (1) или очень быстрое.

Чтобы сделать это немного проще, скажем, я хочу, чтобы все числа (не дроби) a / b между s и t, где 0 <= s <= a / b <t <= M, и 0 <= a, b < = M (b> 0, a и b - целые числа)

пример

Если бы мои дроби были типом данных, который считается только до 6 (M = 6), и я хочу, чтобы плотность была от 0 до 1, ответ был бы 12. Эти числа:

0, 1/6, 1/5, 1/4, 1/3, 2/5, 1/2, 3/5, 2/3, 3/4, 4/5, 5/6.
Что я уже думал

Весьма наивный подход - циклически проходить все возможные дроби и подсчитывать те, которые нельзя упростить. Что-то вроде:

long fractionsIn(double s, double t){
    long density = 0;
    long M = LONG_MAX;
    for(int d = 1; d < floor(M/t); d++){
        for(int n = ceil(d*s); n < M; n++){
            if( gcd(n,d) == 1 )
                density++;
        }
    }
    return density;
}

Ноgcd() очень медленно, поэтому он не работает. Я тоже пытаюсь заниматься математикой, но ничего хорошего не получаю.

Решение

Благодаря ответу @ m69, я сделал этот код дляFraction = pair<Long,Long>:

//this should give the density of fractions between first and last, or less.
double fractionsIn(unsigned long long first, unsigned long long last){
    double pi = 3.141592653589793238462643383279502884;
    double max = LONG_MAX;  //i can't use LONG_MAX directly
    double zeroToOne = max/pi * max/pi * 3; // = approx. amount of numbers in Farey's secuence of order LONG_MAX. 
    double res = 0;

    if(first == 0){
        res = zeroToOne;
        first++;
    }

    for(double i = first; i < last; i++){
        res += zeroToOne/(i * i+1);
        if(i == i+1)
            i = nextafter(i+1, last);   //if this happens, i might not count some fractions, but i have no other choice
    }

    return floor(res);
}

Главное изменение заключается в следующем, что важно для больших чисел (1e17)

Результат

Как я объясняю в начале, я пытался сравнитьFractions с участиемdouble, Вот результат дляFraction = pair<Long,Long> (а такжеВот как я получил плотность двойников)

Density between 0,1:                | 1,2              | 1e6,1e6+1   | 1e14,1e14+1 | 1e15-1,1e15 | 1e17-10,1e17 | 1e19-10000,1e19 | 1e19-1000,1e19
Doubles:        4607182418800017408 | 4503599627370496 | 8589934592  | 64          | 8           | 1            | 5               | 0
Fraction:       2.58584e+37         | 1.29292e+37      | 2.58584e+25 | 2.58584e+09 | 2.58584e+07 | 2585         | 1               | 0

Ответы на вопрос(2)

Ваш ответ на вопрос