Форум программистов, компьютерный форум CyberForum.ru

факториал - C++

Восстановить пароль Регистрация
 
Рейтинг: Рейтинг темы: голосов - 19, средняя оценка - 4.58
Millen
 Аватар для Millen
0 / 0 / 0
Регистрация: 21.11.2010
Сообщений: 17
21.11.2010, 12:21     факториал #1
Задача: написать 3 функции, считающие факториал неотрицательного целого числа от 0 до 170 3 способами:
- с помощью цикла
- рекурсивно
- по формуле Стирлинга
(если число больше 170, надо возвращать бесконечность или код ошибки)

Пользователь вводит с клавиатуры целое число от 0 до 170. Поправлять его, пока не введёт правильно. Вывести на экран значения факториала, посчитанные 3 способами.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
#include "stdafx.h"
#include <iostream>
#include <stdio.h>
#include <conio.h>
#include<math.h>
#include <string>
using namespace std;
const double pi = 4.*atan(1.);
const double e=exp(1.);
 
int cikl (int fact1)
{   unsigned int f = 1; 
    for (int i = 2; i <= fact1; i++) f*=i; 
    return(f);
}
 
int rek (int fact2)
{    if (fact2<=1) return 1;
    else
    return rek(fact2-1)*fact2;
}
 
int sterl(int fact3)
{    unsigned int x; 
    double y,z,w;
    x=pow(fact3,fact3/1.0);
    y=pow(e,-fact3/1.0);
    z=sqrt(2*pi*fact3);
    w=x*y*z;
    return(w);
}
 
int _tmain(int argc, _TCHAR* argv[])
{int n;
for(;;)
{
printf("input n = ");
  scanf("%d",&n);
  if((n>=0)&&(n<=170))
  {printf("%d",cikl(n));
printf("\n");
printf("%d",rek(n));
printf("\n");
printf("%d",sterl(n));
printf("\n");
       break;}
  else
  {printf("\nerror\n\n");}
  }
    return 0;
}
Естественно получается переполнение. Подскажите, пожалуйста, как его обойти и дойти до 170! ? Или нужно было реализовывать каким-то иным способом? Буду благодарен за советы)
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
21.11.2010, 12:21     факториал
Посмотрите здесь:

C++ факториал
C++ Факториал (n-1)!
факториал в с++ C++
C++ Факториал
C++ Факториал Си
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
silent_1991
Эксперт C++
4938 / 3014 / 149
Регистрация: 11.11.2009
Сообщений: 7,024
Завершенные тесты: 1
21.11.2010, 12:44     факториал #2
Вам надо написать длинную арифметику. Т.е. реализовать собственные операции сложения и умножения над длинными числами. И в абсолютно стандартных реализациях разных функций факториала применять не обычное умножение и сложение, а свои собственные, заранее реализованные операции.
Само длинное число можно хранить в массиве, один разряд - одна ячейка.
selevit
 Аватар для selevit
79 / 75 / 3
Регистрация: 08.10.2008
Сообщений: 296
21.11.2010, 13:12     факториал #3
Цитата Сообщение от silent_1991 Посмотреть сообщение
Вам надо написать длинную арифметику
Зачем? для вычисления факториала 170 хватит обычного long double

вот рекурсивно
silent_1991
Эксперт C++
4938 / 3014 / 149
Регистрация: 11.11.2009
Сообщений: 7,024
Завершенные тесты: 1
21.11.2010, 13:26     факториал #4
Ха, а ведь и вправду, именно 170! - граница для стандартного long double. А я привык, что люди обычно сталкиваются с проблемами с факториалом, когда число в стандартный тип не влезает, ну и посоветовал стандартно длинную арифметику)))
selevit
 Аватар для selevit
79 / 75 / 3
Регистрация: 08.10.2008
Сообщений: 296
21.11.2010, 13:29     факториал #5
Вот с помощью цикла

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include <iostream>
using namespace std;
 
long double fact(int N)
{
    long double fact = N;
    if(N < 0) // если пользователь ввел отрицательное число
        return 0; // возвращаем ноль
    if (N == 0) // если пользователь ввел ноль,
        return 1; // возвращаем факториал от нуля - не удивляетесь, но это 1 =)
    else
    {
        for (int i = N - 1; i > 0; i--) // вычисляем факториал с помошью цикла
            fact = fact * i;
        return fact; // возвращаем результат.
    }
}
 
int main()
{
    int N;
    setlocale(0,""); // Включаем кириллицу
    cout << "Введите число для вычисления факториала: ";
    cin >> N;
    cout << "Факториал для числа " << N << " = " << fact(N) << endl << endl; // fact(N) - функция для вычисления факториала.
    return 0;
}
silent_1991
Эксперт C++
4938 / 3014 / 149
Регистрация: 11.11.2009
Сообщений: 7,024
Завершенные тесты: 1
21.11.2010, 13:30     факториал #6
Циклом можно так:

C++
1
2
3
4
5
6
7
long double fact(long double n)
{
    for (int i = static_cast< int >(n - 1); i >= 1; i--)
        n *= static_cast< long double >(i);
 
    return n == 0.0 ? 1.0 : n;
}
volovzi
266 / 168 / 8
Регистрация: 14.03.2010
Сообщений: 501
21.11.2010, 13:37     факториал #7
Не успел ответить...
Только поправка: 170 — граница для дабла, а для длинного дабла она ещё выше.
C++
1
2
3
4
5
6
7
8
9
10
11
12
#include <iostream>
#include <iomanip>
 
double factorial (double x) { return x <= 1 ? 1 : x * factorial(x - 1); }
 
int main (int argc, char * const argv[]) {
    double x;
    
    while (std::cin >> x) std::cout << std::setprecision(15) << factorial(x) << std::endl;
 
    return 0;
}
silent_1991
Эксперт C++
4938 / 3014 / 149
Регистрация: 11.11.2009
Сообщений: 7,024
Завершенные тесты: 1
21.11.2010, 13:43     факториал #8
На многих компиляторах sizeof(long double) == sizeof(double)
selevit
 Аватар для selevit
79 / 75 / 3
Регистрация: 08.10.2008
Сообщений: 296
21.11.2010, 13:47     факториал #9
вот по формуле стерлинга

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include <iostream>
#include <cmath>
using namespace std;
 
long double fact(int N)
{
    long double pi = 3.1415926535897932384626433832795;
    long double e = 2.718281828459045235360287471352662497757;
    long double fact =  sqrt(double(2) * pi * N) * pow(double(N), double(N)) * pow(e, -N);;
    if(N < 0) // если пользователь ввел отрицательное число
        return 0; // возвращаем ноль
    if (N == 0) // если пользователь ввел ноль,
        return 1; // возвращаем факториал от нуля - не удивляетесь, но это 1 =)
    else
        return fact; // возвращаем результат;
}
 
int main()
{
    int N;
    setlocale(0,""); // Включаем кириллицу
    cout << "Введите число для вычисления факториала: ";
    cin >> N;
    cout << "Факториал для числа " << N << " приближенно равен " << fact(N) << endl << endl; // fact(N) - функция для вычисления факториала.
    return 0;
}
Добавлено через 2 минуты
у меня на 32 битной семере в VS 2008 даже unstgned long double не вычисляет больше 170 =)
silent_1991
Эксперт C++
4938 / 3014 / 149
Регистрация: 11.11.2009
Сообщений: 7,024
Завершенные тесты: 1
21.11.2010, 13:48     факториал #10
У меня на 64битной на VS2010 тоже, ибо компилятору захотелось, чтобы sizeof(long double) == sizeof(double) == 8
Millen
 Аватар для Millen
0 / 0 / 0
Регистрация: 21.11.2010
Сообщений: 17
21.11.2010, 14:15  [ТС]     факториал #11
silent_1991, selevit, volovzi, спасибо большое что откликнулись!
silent_1991
21.11.2010, 14:20
  #12

Не по теме:

Millen, "Спасибо" очень хорошо выражается в нажатии кнопки "+1 Спасибо" внизу сообщения

selevit
 Аватар для selevit
79 / 75 / 3
Регистрация: 08.10.2008
Сообщений: 296
21.11.2010, 14:26     факториал #13
Цитата Сообщение от silent_1991 Посмотреть сообщение

Не по теме:

Millen, "Спасибо" очень хорошо выражается в нажатии кнопки "+1 Спасибо" внизу сообщения


Не по теме:

Эх, silent_1991, не в репутации счастье...

Цитата Сообщение от silent_1991
Ты что с ума сошел, а в чем же еще?

silent_1991
21.11.2010, 14:33
  #14

Не по теме:

selevit, улыбнуло

MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
19.02.2013, 01:08     факториал
Еще ссылки по теме:

C++ Факториал
факториал С++ C++
Факториал C++

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
anton_zenit
0 / 0 / 0
Регистрация: 21.12.2012
Сообщений: 88
19.02.2013, 01:08     факториал #15
А как дополнить программу так, чтобы при вводе дробного или отрицательного числа он выводил ошибку? заранее спасибо
Yandex
Объявления
19.02.2013, 01:08     факториал
Ответ Создать тему
Опции темы

Текущее время: 13:57. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru