Модераторы: bsa

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Задача с факториалами, Найти количество цифр n!(n 10^9) 
V
    Опции темы
altairaimenov
Дата 3.3.2015, 18:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 14
Регистрация: 3.3.2015

Репутация: нет
Всего: нет



Найти количество цифр n!(n 10^9)

Пример:

10

Вывод:

7

Поясняю 10! = 3628800, тут 7 цифр

Это сообщение отредактировал(а) altairaimenov - 3.3.2015, 18:28
PM MAIL   Вверх
sQu1rr
Дата 3.3.2015, 18:53 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 597
Регистрация: 11.11.2008
Где: london

Репутация: 3
Всего: 13



В целом числе ровно floor(log(x)) + 1 цифр. (log10 разумеется имеется ввиду)

Можно решить апромиксацией стирлинга: http://en.wikipedia.org/wiki/Stirling%27s_approximation

То есть:

Найти a = sqrt(2*PI * n) * (n/e)^n
Потом b = a * (1 + 1/(12*n - 1))
где PI - это число пи, а e - число ейлера

Найти кол-во цифр в a и b. Если одинаковое то ответ есть, если не одинаковое, что будет редко, то наверное можно как-то подругому проверить. Пока других идей в голову не лезет

Пример:

n = 10
a = 3598695.[...]
b = 3628936.[...]

кол-во цифр в а = 7
кол-во цифр в b = 7
ответ 7

Это сообщение отредактировал(а) sQu1rr - 3.3.2015, 19:05
PM MAIL Skype GTalk   Вверх
kemiisto
Дата 3.3.2015, 18:56 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Дикий Кот. =^.^=
****
Награды: 1



Профиль
Группа: Участник Клуба
Сообщений: 3292
Регистрация: 29.7.2007

Репутация: 5
Всего: 160



Во-первых, это однозначно в "Центр помощи".
Во-вторых, язык то какой: С или С++?

Общая идея такова.
  • Число цифр в числе m можновычислить как ceil(log10(m)).
  • Факториал n! = 1 * 2 * ... * n-1 * n.
  • Значит число цифр в n! равно ceil(log10(n!)) = ceil(log10(1 * 2 * ... * n-1 * n)) = ceil(log10(1) + log10(2) + ... + log10(n-1) + log10(n)).
На сишечке на коленках как-то так:
Код

#include <math.h>
#include <stdio.h>

int main()
{
    long n, i;
    double sum;
    
    printf("> ");
    scanf("%ld", &n);
    
    if (n > 0) {
        /* log(1) + ... + log(n-1) + log(n) */
        sum = 0;
        for (i = 1; i <= n; ++i) {
            sum += log10((double) i);
        }
        
        /* floor[(log(1) + ... + log(n-1) + log(n))] + 1 */
        sum = floor(sum) + 1;
        
        printf("%ld! содержит %.0f цифр.\n", n, sum);
    } else {
        printf("\"%ld\" не является натуральным числом.\n", n);
    }
    
    return 0;
}


Добавлено @ 18:59
Цитата(sQu1rr @  3.3.2015,  17:53 Найти цитируемый пост)
Можно решить апромиксацией стирлинга: http://en.wikipedia.org/wiki/Stirling%27s_approximation

Да не, не надо тут никаких аппроксимаций. Танцуем от того, что логарифм произведения равен сумме логарифмов. smile 

Это сообщение отредактировал(а) kemiisto - 3.3.2015, 19:07


--------------------
PM MAIL WWW GTalk Jabber   Вверх
sQu1rr
Дата 3.3.2015, 19:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 597
Регистрация: 11.11.2008
Где: london

Репутация: 3
Всего: 13



Цитата(kemiisto @  3.3.2015,  15:56 Найти цитируемый пост)
ceil(log10(m)).

ceil(log10(100)) = ceil(2.0) = 2 smile

Добавлено через 1 минуту и 1 секунду
Цитата(kemiisto @  3.3.2015,  15:56 Найти цитируемый пост)
Да не, не надо тут никаких аппроксимаций. Танцуем от того, что логарифм произведения равен сумме логарифмов. smile  


Цитата(altairaimenov @  3.3.2015,  15:27 Найти цитируемый пост)
(n 10^9)

Слишком много считать не?
PM MAIL Skype GTalk   Вверх
kemiisto
Дата 3.3.2015, 19:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Дикий Кот. =^.^=
****
Награды: 1



Профиль
Группа: Участник Клуба
Сообщений: 3292
Регистрация: 29.7.2007

Репутация: 5
Всего: 160



sQu1rr, тоже верно. Таки floor(log10(m)) + 1 всегда будет работать.

Добавлено через 4 минуты и 54 секунды
Цитата(sQu1rr @  3.3.2015,  18:00 Найти цитируемый пост)
Слишком много считать не? 

В смысле, долго? А кому сейчас легко? smile Зато, наверняка.

Добавлено через 5 минут и 58 секунд
Цитата
> 1000000000
1000000000! содержит 8565705523 цифр.

Меньше минуты на моём старье. Меня устраивает. smile 

Это сообщение отредактировал(а) kemiisto - 3.3.2015, 19:06


--------------------
PM MAIL WWW GTalk Jabber   Вверх
sQu1rr
Дата 3.3.2015, 19:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 597
Регистрация: 11.11.2008
Где: london

Репутация: 3
Всего: 13



Цитата(kemiisto @  3.3.2015,  16:04 Найти цитируемый пост)
Меньше минуты на моём старье. Меня устраивает.

Ну питон не думая это решает. Зачем утруждать комп ненужным
PM MAIL Skype GTalk   Вверх
kemiisto
Дата 3.3.2015, 21:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Дикий Кот. =^.^=
****
Награды: 1



Профиль
Группа: Участник Клуба
Сообщений: 3292
Регистрация: 29.7.2007

Репутация: 5
Всего: 160



Цитата(sQu1rr @  3.3.2015,  18:26 Найти цитируемый пост)
Ну питон не думая это решает. Зачем утруждать комп ненужным 

Не совсем понял, о чём ты. Точнее, совсем не понял.


--------------------
PM MAIL WWW GTalk Jabber   Вверх
sQu1rr
Дата 3.3.2015, 23:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 597
Регистрация: 11.11.2008
Где: london

Репутация: 3
Всего: 13



Примерно так: "Даже такой медленный интерпретируемый язык как питон, решает эту задачу моим способом меньше чем за секунду (точнее моментально), а не за минуту на С. Зачем мучать свое железо вычеслениями, когда можно сделать проще - и самому не ждать и железо не утруждать."
PM MAIL Skype GTalk   Вверх
kemiisto
Дата 4.3.2015, 00:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Дикий Кот. =^.^=
****
Награды: 1



Профиль
Группа: Участник Клуба
Сообщений: 3292
Регистрация: 29.7.2007

Репутация: 5
Всего: 160



Цитата(sQu1rr @  3.3.2015,  22:42 Найти цитируемый пост)
Примерно так: "Даже такой медленный интерпретируемый язык как питон, решает эту задачу моим способом меньше чем за секунду (точнее моментально), а не за минуту на С. Зачем мучать свое железо вычеслениями, когда можно сделать проще - и самому не ждать и железо не утруждать."

Ну, release-версия, собранная с -O3, считает за 15 секунд. smile Собственно, твоего кода я в топике не вижу, но если он основан на приближении Стирлинга, то ничего удивительного, что у тебя быстрее получилось "даже" на Python. Вот только какой смысл сравнивать время получения приближённого и точного* решения? Ежу понятно, что приближённый ответ можно получить быстрее. smile 

Это сообщение отредактировал(а) kemiisto - 4.3.2015, 00:17


--------------------
PM MAIL WWW GTalk Jabber   Вверх
baldina
Дата 4.3.2015, 11:41 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

Репутация: 15
Всего: 101



а нужен ли точный ответ? для 1е9 число цифр по первому приближению стирлинга совпадает с вашей суммой.
погрешность определения числа цифр гораздо меньше, чем погрешность самого факториала.
кстати, с чего вы взяли, что ваш результат точен: и логарифм, и суммирование это заведомо неточные операции.

Добавлено через 59 секунд
http://ideone.com/KCrQmy
PM MAIL   Вверх
kemiisto
Дата 4.3.2015, 12:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Дикий Кот. =^.^=
****
Награды: 1



Профиль
Группа: Участник Клуба
Сообщений: 3292
Регистрация: 29.7.2007

Репутация: 5
Всего: 160



Цитата(baldina @  4.3.2015,  10:41 Найти цитируемый пост)
а нужен ли точный ответ?

Откуда мне знать. ТС так и не объявлялся. Однако обычно, если не указано иное, нужен именно точный ответ. Зачем считать заведомо приближённо, если можно посчитать точно? Дался вам этот Стирлинг. smile 

Цитата(baldina @  4.3.2015,  10:41 Найти цитируемый пост)
кстати, с чего вы взяли, что ваш результат точен: и логарифм, и суммирование это заведомо неточные операции.

Да ну прямо счаз. Там double всё-таки. Гарантированно 15–17 значащих цифр. Аргументы логарифма до 10^9, сами значения от 0 до 9. Каким образом Вы тут собрались накопить ошибку при 15–17 значащих цифрах? Арифметика с плавающей точкой, конечно, неточная, но она ж не всегда настолько неточная, чтоб за компьютер вообще не садиться. smile 


--------------------
PM MAIL WWW GTalk Jabber   Вверх
baldina
Дата 4.3.2015, 13:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

Репутация: 15
Всего: 101



на 1e9 сложениях при 15 значащих цифрах может накопиться погрешность порядка 1e-6. пустячок, но приятно))
PM MAIL   Вверх
sQu1rr
Дата 4.3.2015, 14:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 597
Регистрация: 11.11.2008
Где: london

Репутация: 3
Всего: 13



Цитата(kemiisto @  3.3.2015,  21:16 Найти цитируемый пост)
Ну, release-версия, собранная с -O3

взаимоисключающие параграфы однако smile

Цитата(kemiisto @  3.3.2015,  21:16 Найти цитируемый пост)
то ничего удивительного, что у тебя быстрее получилось "даже" на Python. Вот только какой смысл сравнивать время получения приближённого и точного* решения

Ну так мой аргумент же скорость. Я полностью согласен что можно считать и не приближением, и будет меньше погрешность скорее всего, но зачем?

Цитата(kemiisto @  4.3.2015,  09:27 Найти цитируемый пост)
нужен именно точный ответ

Точный ответ в кол-ве цифр, а не факториала. Приблежение стирлинга с этим вполне хорошо справляется.

Да и вообще спор бесмыслен. вы предложили один способ, я второй. В отличие от вас, я не говорю про ваш способ "не нужен". Для ОП это будет возможность попробовать оба, и еще и математики подучить.
PM MAIL Skype GTalk   Вверх
kemiisto
Дата 4.3.2015, 15:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Дикий Кот. =^.^=
****
Награды: 1



Профиль
Группа: Участник Клуба
Сообщений: 3292
Регистрация: 29.7.2007

Репутация: 5
Всего: 160



Цитата(sQu1rr @  4.3.2015,  13:06 Найти цитируемый пост)
взаимоисключающие параграфы однако

Почему? smile 

Цитата(sQu1rr @  4.3.2015,  13:06 Найти цитируемый пост)
Ну так мой аргумент же скорость. Я полностью согласен что можно считать и не приближением, и будет меньше погрешность скорее всего, но зачем?

Бывает, что нужно быть абсолютно уверенным в ответе, и ради этого можно и подождать.

Цитата(sQu1rr @  4.3.2015,  13:06 Найти цитируемый пост)
Точный ответ в кол-ве цифр, а не факториала. Приблежение стирлинга с этим вполне хорошо справляется.

Вы можете гарантировать (доказать), что для всех чисел до 10^9 использование формулы Стирлинга даст верное число цифр?

Это сообщение отредактировал(а) kemiisto - 4.3.2015, 15:13


--------------------
PM MAIL WWW GTalk Jabber   Вверх
sQu1rr
Дата 4.3.2015, 15:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 597
Регистрация: 11.11.2008
Где: london

Репутация: 3
Всего: 13



Цитата(kemiisto @  4.3.2015,  12:12 Найти цитируемый пост)
Вы можете гарантировать (доказать), что для всех чисел до 10^9 использование формулы Стирлинга даст верное число цифр?

Код

#include <iostream>
#include <cmath>
using namespace std;

const int N = 1000000000;

void stirlingLn(double x) {
  double a = log10(sqrt(2*acos(-1.0)*x))+x*log10(x/exp(1));
  double b = a + log10(1.0+1.0/(12*x+1.0));
  unsigned long long al = floor(a) + 1;
  unsigned long long bl = floor(b) + 1;
  if (al != bl) {
    cout << "Ambiguous case for x=" << x << endl;
  }
}

int main() {
    for (int i = 0; i < N; ++i) {
        stirlingLn(double(i));
    }
}

У меня нет компилятора под рукой - проверьте пожалуйста. А вы можете за разумное время гарантировать то же самое про свой метод? Не считая матиматически доказуемой незначительной погрешности, которая все таки может сыграть свою роль, хоть это и настолько маловероятно, что даже проверять не стоит.


Цитата(kemiisto @  4.3.2015,  12:12 Найти цитируемый пост)
Почему? smile 

Ну релиз в -O3 не компилируется. -O3 сам по себе подрузамевает тестинг.


Цитата(kemiisto @  4.3.2015,  12:12 Найти цитируемый пост)
Бывает, что нужно быть абсолютно уверенным в ответе, и ради этого можно и подождать.

Согласен. Если это нужно - ваш способ - верный путь.
PM MAIL Skype GTalk   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Для новичков"
JackYF
bsa

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, bsa.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Для новичков | Следующая тема »


 




[ Время генерации скрипта: 0.1451 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.