Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Общие вопросы по .NET и C# > Найти ошибку в расчете


Автор: sulyco 2.2.2014, 13:53
Консольное приложение. Приведенный расчет - часть другой программы. Результирующие переменные при выполнении цикла должны стремиться к своим значениям. Одна (W2) послушно ползет к своему значению 5,82. W1 с 17-го шага отпрыгивает и далее ведет себя совершенно не понятно. Построил расчет в экселе - все сходится. Подскажите в чем проблема? ПО результатам эксела переполнения переменных быть не должно, а расчет скривился...

Код

static void Main(string[] args)
        {
            double L1 = 0.02736; // 00554250319;
            double L2 = 0.01357; // 75222627199;
            double p1;
            double p2;
            int t;

            for (t = 0; t <= 30; t++)
            {
                p1 = 1e-10;
                p2 = 1e-10;

                for (int i = 0; i <= t; i++)
                {
                    for (int j = 0; j <= t; j++)
                    {
                        if (i > j) p1 = p1 + 1 / (K(L1, i) * K(L2, j));
                        if (j > i) p2 = p2 + 1 / (K(L1, i) * K(L2, j));
                    }

                }
                double W1 = 1 / p1;
                double W2 = 1 / p2;

                Console.WriteLine("для t={2}: \t1,53:= {0}, \t5,82:= {1}", W1, W2, t);
            }
           
            

            Console.ReadLine();
        }

        public static int Fact(int n)
        {
            int i;
            int Result = 1;
            for (i = 2; i <= n; i++)
                Result = Result * i;
            return Result;
        }

        public static double K(double L, int i)
        {
            double Res = Fact(i) * Math.Exp(L * 94) / Math.Pow((L * 94), i);
            return  Res;
        }
    }


В делфи такой расчет работает, правда с типом Extended, который поддерживает диапазон от 3.37 х 10(-4932) до 1.18 x 10(4932). Поэтому подумалось о переполнении double

Автор: jonie 2.2.2014, 14:53
и ? мы чем вам помочь должны?

Автор: sulyco 2.2.2014, 15:27
помощь может заключаться в объяснении разного поведения расчета для двух случаев исходных данных. Действительно ли "опрокинулась" переменная? Как ведет себя расчет на другом компе? А может это от каких-то настроек зависит?
Ну не знаю. Эксел считает, а NET -не может. Так бывает?

Автор: jonie 2.2.2014, 19:34
Так бывает, да. Особенно если перенесено неправильно.... но мы не знаем где правильно, конечно.

Автор: Экскалупатор 2.2.2014, 20:11
http://msdn.microsoft.com/ru-ru/library/system.double(v=vs.110).aspx
прочти раздел про точность и представление десятичных дробей в двоичном виде, отсюда часто возникают нестыковки. Да и хотелось бы больше информации о том что должно получаться в приведенном расчете, а не догадываться что же должно произойти, а что происходит.

Автор: sulyco 2.2.2014, 20:40
Спасибо всем за участие.
Разбирался с составляющими по отдельности. Обнаружил, что "кривит" факториал. Начиная с позиции 13!. Хотя "вместимость" int'а вроде и не превышает. Попытался "ручками" посмотреть. Начал вбивать формулу типа
int f=1*2*3*4...
До позиции *12 всё было хорошо. При простановке *13 строчка подчеркнулась красным и по наведению курсора выползло сообщение "Переполнение при выполнении операции во время компиляции в режиме с проверкой" (компилятор - студия2010)
Замена int на long результатов не дала.
Помогла замена типа факториала Fact с int на double, старт расчета факториала начал с дублёвой 0,000001, что позже компенсировал в дальнейшем расчете.

Так, что будьте бдительны при применении простейшей, казалось бы функции, факториал.
Отмечаю вопрос решенным.

Автор: Экскалупатор 2.2.2014, 20:42
переполнение при вычислении факториала.
исправь:
Код

 public static int Fact(int n)
        {
            checked
            {
                int i;
                int Result = 1;
                for (i = 2; i <= n; i++)
                    Result = Result*i;
                return Result;
            }
        }


Добавлено через 50 секунд
чорт, пока печатал и смотрел уже появился ответ... ну главное что проблема решилась ))) удачи

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)