![]() |
|
|
![]()
|
|
| EKoshelev |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 509 Регистрация: 1.9.2004 Репутация: нет Всего: нет |
maxim1000
В том смысле, что считать сумму натуральных логарифмов по всем числам, а потом экспоненту по получившемуся. Может подскажешь, как разложить в ряд натуральный логарифм??? Там можно будет покумекать с многоразрядными делами потом... Добавлено @ 16:08 А, ну понял. Ну всё равно подскажи, как логарифм разложить. -------------------- Вежливым и адекватным предлагаю общаться на "ты". |
|||
|
||||
| maxim1000 |
|
||||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 3334 Регистрация: 11.1.2003 Где: Киев Репутация: 33 Всего: 110 |
точнее в переходе от основания 10 к основанию e. т.к. разница в сложности будет не больше одной операции деления а вообще у логарифмов и подобных функций есть недостаток: их результат очень часто бывает иррациональным, что приводит к неточности представления информации, в этом случае можно говорить только о приблизительном значении факториала, а значит, последним его цифрам доверять вообще не стоит...
ряда не помню к тому же есть разные ряды (Тейлора, Фурье) если в Тейлора, то попробуй разложить ln(1+x) с помощью производных кроме того, можно еще искать логарифм с помощью бисекции (правда, тогда придется реализовывать еще и операцию корня) -------------------- qqq |
||||
|
|||||
| Aslan74 |
|
|||
|
Новичок Профиль Группа: Участник Сообщений: 10 Регистрация: 23.12.2004 Репутация: нет Всего: нет |
Надо выделить степени 2 и 5, встречающиеся в разложениях i = 2, n
на множители, и посчитать их степени отдельно. Потом, если степень 2 больше, домножить на 2 в степени (степень 2 - степень 5), иначе 5 в степени (степень 5 - степень 2), остаток пойдет в замыкающие нули. Причем все умножения делаются только для последней цифры, без "длинной" арифметики // отделить степени 2 и 5 // разбить число на C * 2^x2 * 5^x5 void Decompose(int& n, int& x2, int& x5) { for (x2 = 0; n%2 == 0; n/= 2, x2++); for (x5 = 0; n%5 == 0; n/= 5, x5++); } // последняя ненулевая цифра n! int Factorial(int n) { int res = 1, n2 = 0, n5 = 0; for (int i = 2; i <= n; i++) { int r= i, x2, x5; Decompose(r, x2, x5); // отдельно домножаем степени 2 и 5, отдельно остальное res= (res * r)%10; // взять последнюю цифру n2+= x2; n5+= x5; } // домножить на 2 или 5 if (n2 > n5) for (int i = 0; i < n2-n5; i++) res= (res * 2)%10; // взять последнюю цифру else if (n2 < n5) for (int i = 0; i < n5-n2; i++) res= (res * 5)%10; // взять последнюю цифру return res; } P.S. Вычисляя n! для проверки обнаружил неприятный факт - в C Builder нет range checking (проверки переполнения) Добавлено @ 20:35 Надо выделить степени 2 и 5, встречающиеся в разложениях i = 2, n на множители, и посчитать их степени отдельно. Потом, если степень 2 больше, домножить на 2 в степени (степень 2 - степень 5), иначе 5 в степени (степень 5 - степень 2), остаток пойдет в замыкающие нули. Причем все умножения делаются только для последней цифры, без "длинной" арифметики // отделить степени 2 и 5 // разбить число на C * 2^x2 * 5^x5 void Decompose(int& n, int& x2, int& x5) { for (x2 = 0; n%2 == 0; n/= 2, x2++); for (x5 = 0; n%5 == 0; n/= 5, x5++); } // последняя ненулевая цифра n! int Factorial(int n) { int res = 1, n2 = 0, n5 = 0; for (int i = 2; i <= n; i++) { int r= i, x2, x5; Decompose(r, x2, x5); // отдельно домножаем степени 2 и 5, отдельно остальное res= (res * r)%10; // взять последнюю цифру n2+= x2; n5+= x5; } // домножить на 2 или 5 if (n2 > n5) for (int i = 0; i < n2-n5; i++) res= (res * 2)%10; // взять последнюю цифру else if (n2 < n5) for (int i = 0; i < n5-n2; i++) res= (res * 5)%10; // взять последнюю цифру return res; } P.S. Вычисляя n! для проверки обнаружил неприятный факт - в C Builder нет range checking (проверки переполнения) |
|||
|
||||
| ovr2000 |
|
|||
|
Новичок Профиль Группа: Участник Сообщений: 11 Регистрация: 30.11.2004 Репутация: нет Всего: нет |
Зачем же так сложно.
Всего, при перемножении n! будет встречено множителей с 5-ками: целая часть(n/5) + челая часть (n/25) и т.д. Это меньше, чем Сумма от 1 до k(k понятно количество членов получившегося ряда) (n/5^i, i=1бл), а это геометрическая прогрессия, значит сумма(Выше) равна n*((1/5-1/5^(k+1))/(1-1/5) < n/4 (это оченка количества 5 во всем числе n!) Если мы возьмем только первые степени двойки хотя бы от трех множителей из каждого десятка (а там ведь каждый второй - четный), то это будет n*0.3>n*/4=n*0.25 Значит посчитав 5-ки, можно будет отнять только 2 от четных чисел, не считая все множители Чтобы зря не множить на 10, сразу отнимем их количество от 5, посчитав ряд (я имею в виду точно, а не приближенно) В результате получится только три цикла, безо всякого вложения. Например:
Добавлено @ 12:42 Заметьте, все вычисления идут с типом integer, кроме самого числа, которое может быть и очень большим Добавлено @ 12:44 Да, кстати, третий раз делить на 2 (case 6) можно ненадо, т.к. мы уже отняли десятки |
|||
|
||||
| EKoshelev |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 509 Регистрация: 1.9.2004 Репутация: нет Всего: нет |
maxim1000, а по моему дак всё будет не только рациональным, но ещё и целым (ну или типа 123.999999934345793487), я на маленьких числах пробовал.
Aslan74 и ovr2000, я чё-то нить вашего разговора не поймал... -------------------- Вежливым и адекватным предлагаю общаться на "ты". |
|||
|
||||
| ovr2000 |
|
|||
|
Новичок Профиль Группа: Участник Сообщений: 11 Регистрация: 30.11.2004 Репутация: нет Всего: нет |
Да суть в порядке чисел, в алгоритмах не используются числа больше сотни, за исключением самого числа N
Именно это я хотел сказать, т.к. все алгоритмы, кроме последних двух , при определенных числах N уходили в переполнение |
|||
|
||||
| GePo |
|
|||
![]() Бывалый ![]() Профиль Группа: Участник Сообщений: 166 Регистрация: 30.3.2003 Где: Москва Репутация: нет Всего: 3 |
да когда ж вы читать научитесь. Я уже давно написал решение, которое не переполняется, в нем есть все "гениальные идеи", которые потом всем пришли, и вообще то с математически доказанной верностью.
Похоже кому-то влом смотреть чье-то решение, кроме своего любимого... --------------------
|
|||
|
||||
| EagleThePredator |
|
|||
![]() Новичок Профиль Группа: Участник Сообщений: 4 Регистрация: 24.11.2005 Репутация: нет Всего: нет |
GePo
|
|||
|
||||
| sadovoya |
|
|||
|
Новичок Профиль Группа: Участник Сообщений: 1 Регистрация: 15.10.2006 Репутация: нет Всего: нет |
Может, это не совсем то, что нужно, но вдруг кому-нибудь пригодится. У меня есть небольшой пример на Delphi работы с очень большими (по порядку величины) целыми числами. Демонстрируется лишь сам принцип - разделение числа на значущую часть и порядок. Адрес: http://sadovoya.narod.ru/BIG_NUMBERS.ZIP
|
|||
|
||||
| integral |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 278 Регистрация: 3.7.2006 Где: Dnipropetrovs' ;k, Ukraine Репутация: нет Всего: нет |
А вот пример на Java, на своей машине я смог вычеслить 100001! за 9 мин 24 сек:
private String calkFacktorial(String str) { if(str.equals("0")) return "1"; BigInteger i = new BigInteger("1"); BigInteger n = new BigInteger(str); BigInteger result = new BigInteger("1"); for(; !i.equals(n); i = i.add(BigInteger.ONE)) { result = result.multiply(i); } return result.multiply(n).toString(); } |
|||
|
||||
| esperant0 |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 714 Регистрация: 20.5.2005 Репутация: 4 Всего: 14 |
а я за своей за 12 секунд считал -------------------- Student->Teacher Assistant ->Research assistant->Microsoft Software Development Engineer Пользователь получил наказание за то, что проигнорировал замечание которое было написано модератором а затем стерто и которое он - пользователь не мог видеть. |
|||
|
||||
![]()
|
| Правила форума "Алгоритмы" | |
|
|
Форум "Алгоритмы" предназначен для обсуждения вопросов, связанных только с алгоритмами и структурами данных, без привязки к конкретному языку программирования и/или программному продукту.
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, maxim1000. |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | Алгоритмы | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |