Программа предназначена для расчета суммирования ряда 1/1! + 2/2! + ..... до числа, указанного в качестве ввода.

Вот код, который я написал.

/ * Я использовал 5 переменных и вложенные циклы. Я даже не знаю, хороший ли это способ написать программу * /

Вопрос: когда я просто помещаю круглые скобки, как показано (под полным кодом), вывод будет другим, почему это происходит?

#include <stdio.h>
#include <conio.h>
int main ()
{
    int a,i,n;
    float sum=0,prod;
    printf ("Enter the number\n");
    scanf ("%d",&a);
    for (i=1;i<=a;i++)
    {   
        for (n=1;n<=i;n++)
        {   
            for (prod=1;n<=i;n++)
                prod = prod * 1/n;
        }
        sum = sum + prod*i;
    }
    printf ("sum = %f\n ",sum);
    getch();
    return 0;
}

С круглыми скобками

prod = prod * (1/n);

Пожалуйста, помогите мне с этим и заранее спасибо.

c
-1
yeshwanth 20 Фев 2016 в 23:48

8 ответов

Лучший ответ

C работает слева направо, поэтому он видит

prod = prod * 1 / N;

И он считает, что prod равно prod на 1, а затем делится на n. Помещая скобки вокруг 1 / N, вы говорите C, что prod умножается на 1 / N, а не наоборот. Это точно так же, как в математике, если вы заключите в скобки то, что будет оцениваться отдельно, а затем снова поместить в порядок после завершения.

0
Careful Now 20 Фев 2016 в 20:54

Причина в том, что ваш код не эквивалентен соответствующему математическому выражению. Помните, что / в C не является делением, это целочисленное деление.

Он эффективно добавляет в оператор математическую функцию Floor. С чисто математической точки зрения вы обнаружите, что:

Prod * floor (1/n) отличается от Floor (prod * 1/n).

Вам нужна версия без скобок в коде: prod * 1/n

Но вам также нужно будет добавлять остаток к вашей сумме на каждой итерации, поэтому:

Prod = (prod /n) + (prod % n);

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

Изменить: я считаю, что в C, если один из операндов в операторе / является числом с плавающей запятой, он будет выполнять деление с плавающей запятой. В этом случае вам не нужно добавлять остаток к сумме:

Prod = prod / n;

0
mech 20 Фев 2016 в 21:20

Без скобок утверждение

prod = prod * 1/n;  

Будет проанализирован как

prod = (prod * 1) / n;  

Из-за того же приоритета операндов * и / ассоциируются слева направо. В этом случае prod * 1 делится на n.

Хотя в случае

prod = prod * (1/n); 

1/n всегда приводит к 0 и приводит к разным результатам. Изменив его на

prod = prod * (1.0/n);   

Буду работать.

0
haccks 20 Фев 2016 в 20:56
int a,i,n;
float sum=0,prod;

prod = prod * (1/n);

Что ж, ответ находится в ваших объявлениях: 1 и n - целые числа, а prod - число с плавающей запятой, результатом prod = prod * 1 / n = prod / n и результатом будет желаемое правильное число с плавающей запятой. В то время как prod = prod * (1 / n) будет prod * 0 (для n> 1), потому что 1 / n - это int / int, а результат - int.

0
Alexie Dariciuc 20 Фев 2016 в 20:52

Без скобок оператор разбирается как

prod = (prod * 1) / n;

Поскольку prod является плавающим, proad * 1 также будет плавающим. Тогда деление будет делением с плавающей запятой.

Но если вы добавите круглые скобки, тогда (1/n) будет целочисленным делением, потому что оба операнда являются целыми числами. Таким образом, (1/n) будет равно нулю для n & gt; 1. Тогда и prod будет нулем.

В любом случае ваша программа вызывает неопределенное поведение, потому что prod не был инициализирован.

1
Martin Zabel 21 Фев 2016 в 08:40

prod * 1/n анализируется как (prod * 1)/n и приводит к делению с плавающей запятой.

prod * (1/n) использует целочисленное деление, которое обрезает результат деления (обычно до 0).

1
Michael Burr 20 Фев 2016 в 20:52

прод = прод * (1 / н); // неправильно

Это означает, что сначала выполняется (1/n) - который равен нулю (поскольку оба обрабатываются как int, а 1 меньше n).

прод = прод * 1 / н; // Верный

Это означает, что сначала выполняется prod * 1 (ассоциация слева направо) - результат равен double, поэтому окончательный результат prod * 1/n также является двойным (что является правильным результатом).

1
artm 20 Фев 2016 в 20:51

Вам понадобится всего одна петля. Вот как бы я написал это на Java. Быстро сходится. Этот ряд приближается к значению e.

package math.series;

/**
 * SeriesSum approximates value for e
 * Created by Michael
 * Creation date 2/20/2016.
 * @link https://stackoverflow.com/questions/35528818/parenthesis-effecting-the-output-in-c
 */
public class SeriesSum {

    public static final int DEFAULT_NUM_TERMS = 5;

    public static void main(String[] args) {
        int n = (args.length > 0) ? Integer.parseInt(args[0]) : DEFAULT_NUM_TERMS;
        System.out.println(SeriesSum.summation(n));
    }

    public static double summation(int n) {
        double sum = 0.0;
        double term = 1.0;
        for (int i = 1; i <= n; ++i) {
            term *= i;
            sum += i/term;
        }
        return sum;
    }
}
0
duffymo 20 Фев 2016 в 20:58