[C# 1] Loops - 05. Calculate


1

using System;

class Program

{

static void Main()

{

double res = 1;

int n = int.Parse(Console.ReadLine());

double x = double.Parse(Console.ReadLine());

for (int i = 1; i <= n; i++)

{

res += Factorial(i) / Math.Pow(x, i);

}

Console.WriteLine("{0:F5}", res);

}

public static double Factorial(double number)

{

if (number <= 1)

{

return 1;

}

return number * Factorial(number - 1);

}

}

Здравейте колеги,

Ако някой може да ми помогне и да каже защо ми гърми и вади само 60 точки? Който има някаква идея да казва.

Съжалявам, че кода е така, но не успях да го форматирам.




Отговори



10

Тъй като вече са пуснати правилните тестове, поправям си отговора, за да не се заблуди някой, който чете по-късно. Това вече е правилното решение за 100/100:

using System; class Calculate { static void Main() { ulong n = ulong.Parse(Console.ReadLine()); double x = double.Parse(Console.ReadLine()); ulong factorial = 1; double sum = 1 + 1/x; for (ulong counter = 2; counter <= n; counter++) { factorial = factorial * counter; double pow = Math.Pow(x, counter); sum = sum + (factorial / pow ); } Console.WriteLine("{0:F5}", sum); } }

Оставям все пак старото решение, заради коментарите по-долу.

Ето едно решение за 100/100   85/100

using System;

    class Calculate
    {
        static void Main()
        {
            int n = int.Parse(Console.ReadLine());
            double x = double.Parse(Console.ReadLine());
            int factorial = 1;
            double sum = 1 + 1/x;
            for (int counter = 2; counter <= n; counter++)
            {
                factorial = factorial * counter;
                double pow = Math.Pow(x, counter);
                sum = sum + (factorial / pow );
            }
            Console.WriteLine("{0:F5}", sum);
        }
    }


от Pepi.Ka (922 точки)


3

Благодаря .... цялата сага стана ясна ... 

  int factorial = 1; тази простотиика ако се декларира като не INT ( double в моя случай) всичко отива по дяволите. 

хаха да имам  3 страници със събмитнати варианти 100/ 100 в bgcoder-a в момента ( включително най-първият )


от todorovh (2055 точки)

0
Дааа, и на мен този int factorail ми ядеше главата :D

от tabula (2134 точки)



6
Имахме неправилни тестове - до десетина минутки ще са подменени и решенията ще са оценени наново.

от kon.simeonov (5238 точки)


0
Благогаря за информацията. Ще изчакаме и тогава ще видим.

от dushka.dragoeva (1324 точки)

0
Благодаря :) 

от mitko_98 (143 точки)



0
double factorial;
Те праща направо в коша.
Смени го на int ако искаш да надскочих 30/100.

от StoikoNeykov (2621 точки)


1

Няма логика (или поне на мен ми бяга) BGCoder да приема int, а да не иска long, double,  BigInteger.

Да не говорим, че int прелива при n>12, а по условие имаш 2<=n<=20. оО

Хубаво би било условията, при които BGCoder приема резултатите за тази задача да бъдат коригирани, защото в сегашното положение не са коректни и могат да объркат някои колеги.


от martinboykov (1112 точки)


0

Доста мислих по въпроса и това не идва от БГ Кодер а от самия език C#. Това са мои разсъждения и не претендирам че съм абсолутно права. Когато се оперира в един израз с данни от различен тип както са int (32 bit) и double(64 bit) има автоматично кастване на по- малкия към по големия тип. Ако е long и double  - ще се кастне към лонг, защото целочислената част на double e по-малка от лонг и по този начин се реже всичко след десетичната запетая.

А защо  int factorial = 1; А а не double factorial - прочетете тук и сами ще се досетите.


от dushka.dragoeva (1324 точки)

0
Затова се каства в скоби преди променливата при някои случаи.




1
Все още не разбирам защо ако factorial е int резултатът е 100/100, а ако е ulong - 30/100. N е макс 20, а 20! не се побира в int.



0
На мен макс точки ми даде само с double, но тъй като прави някаква грешка (отклонение след запетайката) накрая извеждам само цялата част. Всички други варианти ми се дънеха. Пробвай направо BigInteger и без това ще ти трябва за следващите задачи. 

от Slavka74 (436 точки)

0
В подкрепа на milen.dobrinov и аз не мога да се съглася нещо с тестовете. При int N = 20 -> N! = 109641728, а при long N = 20 -> N! = 2432902008176640000, с което излиза, че при int числото прехвърля. А BGcoder точно с int дава  100/100. Ето и линк Wikipedia.

от venelingp (1371 точки)


0

Къде греша и защо BgCoder ми дава само 30/100. Разбрах от прочетените коментари как да натаманя резултата, но според мен има нещо доста сбъркано в тестовете. Имам ли грешка в логиката?

using System; public class Calculate { private static void Main() { int n = int.Parse(Console.ReadLine()); double x = double.Parse(Console.ReadLine()); double s = 1.0; double product = 1.0; for (int i = 1; i <= n; i++) { product = product * (i / x); s = s + product; } Console.WriteLine("{0:F5}", s); } }


от marks (354 точки)


0
Логиката е правилна. Би трябвало да работи. При мен обаче също вариантите с директно изчисляване на крайния израз даваха грешка и не можах да ги оправя. Вариантът, който накрая ми даде 100 точки е с отделно изчисляване на числителя и знаменателя и едва след това ги деля и прибавям към натрупващата се сума. Предполагам, че проблема може да идва по някакъв начин от неточността на double и натрупването на грешка с нарастването на i. 

от Slavka74 (436 точки)

0

И аз смятам, че double типа е проблема при изчисления. С този тип доста трябва да се внимава, че си дава floating point грешките. Всичко останало си е нормално. Ако направиш продукта инт обаче, вероятно ще трябва и промяна в логиката, като например вътре в цикъла: product *= i; s += product / Math.Pow(x, i);  

Math.pow също връща double, така че пак проблеми :) Чисто решение е да се имплементира самостоятелно метод който прави повдигане на степен, като този долу:

static double xRaised(double xx, int degree)
        {
            double result = 1;
            for (int i = 1; i <= degree; i++)
            {
                result *= xx;
            }
            return result;
        }


от messenger (552 точки)



1
В подкрепа на milen.dobrinov и аз не мога да се съглася нещо с тестовете. При int N = 20 -> N! = 109641728, а при long N = 20 -> N! = 2432902008176640000, с което излиза, че при int числото прехвърля. А BGcoder точно с int дава  100/100. Ето и линк Wikipedia.

от venelingp (1371 точки)


1
Голяма част от тестовете към задача [C# 1] Loops - 05. Calculate! категорично са грешни.
С този код получавам 30/100:
using System; public class Calculate { private static void Main() { ulong n = ulong.Parse(Console.ReadLine()); double x = double.Parse(Console.ReadLine()); ulong factorialN = 1UL; double productX = 1.0; double sum = 1.0; for (ulong i = 1UL; i <= n; i++) { factorialN *= i; productX *= x; sum += factorialN / productX; } Console.WriteLine("{0:F5}", sum); } }

но ако заменя навсякъде ulong с int получавам 100/100;
int не можеда събере 20! и със сигурност има прехвърляне размера на типа.

Аз не съм присъствено и нямам идея как да се обърна към някой, който може да предприеме нещо, освен чрез форума.

от marks (354 точки)


0
Ами по принцип тук е начина да се обърнеш към трейнърите. Между другото много колеги забелязаха, че на тази задача тестовете са грешни и че при всички положения int -a на факториела прехвърля стойностите, но така дава 100 точки задачата.  

от venelingp (1371 точки)


2
Ще ви сложа нови тестове на задачата утре и ще пусна ретест.

от kon.simeonov (5238 точки)


0

Здравейте колеги,

аз също имам проблем с тази задача. Според мен кода ми е добре, но Bgcoder ми дава 85%. Някой може ли да помогне. Това е кода ми:

using System; class Program { static void Main() { int n = int.Parse(Console.ReadLine()); double x = double.Parse(Console.ReadLine()); double sum = 1; // s = 1 + 1!/x + 2!/x*x + 3!/x*x*x + ...+n!/xn int factorial = 1; double product = 1; for (int i = 1; i <= n; i++) { factorial *= i; product *= x; sum += factorial /product; } Console.WriteLine("{0:F5}",sum); } }

Благодаря предварително.




0

Здравей отново ;) Както на другата тема която си пуснала така и тук заради факториела ти се препълва int-a.. Затова ако смениш int ----> ulong ще ти даде 100/100 :) Пробвах ти кода даде 100/100 :Р Внимавай с избора на типове данни за програмите които пишеш ;) може да те издънят и на изпита :Р

Успех!


от RavenDark (170 точки)

0

Здравей колега,

благодаря! Разбрах си грешката и вече работи. Успех на изпита :-)




0
Тестовете явно вече са сменени. На първитe решениq с long ,както и с BigInteger имам 100/100 а пoследното с int 85/100

от dushka.dragoeva (1324 точки)