Расчет суммы гармоник - PullRequest
       2

Расчет суммы гармоник

1 голос
/ 16 сентября 2011

Я написал программу для вычисления суммы ряда гармоник (1 + 1/2 + 1/3 .. + 1 / n), но у меня возникают проблемы при ее компиляции.Я просматривал код несколько раз, но не вижу никаких синтаксических ошибок [2 появляются, когда я пытаюсь скомпилировать].Моя логика неверна или синтаксическая?

#include <stdio.h>
int main( void ) {

 int v,p,i;
 double x=0;

 printf("Enter a value to calculate the value of this harmonic series: \n");
 scanf("%d",&v);

 if (v<=0) {
   printf("Please enter a POSITIVE number: \n");
   scanf("%d",&p);
   while (i=1; i<=v; i++) {
     x=x+(1/i);  }
     printf("The value for the series is %lf", x);
  }
    else {
      while (i=1; i<=v; i++) {
        x=x+(1/i);
      }
      printf("The value for the series is %lf", x);
    }
  return 0;
}

Спасибо за любую помощь

Ответы [ 5 ]

6 голосов
/ 16 сентября 2011

Все эти while должны быть for, а 1/i должно быть либо 1./i, либо 1/(double)i, потому что в противном случае выполняется целочисленное деление. Кроме того, вам следует реструктурировать поток программ, чтобы избежать дублирования кода.

Но , есть небольшая, но более важная ошибка: из-за того, как работает арифметика с плавающей запятой, вы должны начать суммировать от меньших чисел до больших, иначе вы можете достичь точки, где каждое новое добавление является меньше текущей точности этого double, и сложение не будет иметь эффекта 1 . Итак, ваш for должен быть обратным:

for (i=v; i>=1; i--)
<ч />

Также: вы должны проверить, чтобы возвращаемое значение scanf было равно 1, чтобы убедиться, что пользователь действительно вставил какой-либо действительный числовой ввод. И , спецификатор printf для double s равен %f, без l.

Учитывая все это, вы можете переписать программу следующим образом:

#include <stdio.h>

int main( void )
{
    int v=0,i,ch;
    double x=0.;

    printf("Enter a value to calculate the value of this harmonic series: ");

    /* The loop calls the scanf, and is repeated as far as the user continues to
       write garbage */
    while(scanf("%d",&v)==0 || v<=0)
    {
        printf("Please enter a POSITIVE number: ");

        /* Empty the input buffer to remove the eventual garbage; the logic is
           a bit convoluted to handle the case where the user enters EOF */
        while((ch=getchar())!='\n')
            if(ch==EOF)
                return 1;
    }

    /* perform the actual sum - done from smallest to biggest term */
    for (i=v; i>=1; i--)
        x+=1./i;

    printf("The value for the series is %f\n", x);
    return 0;
}
<ч />
  1. Для ряда гармоник это на самом деле практически невозможно - вам нужно перейти к действительно большим числам, чтобы заметить некоторую разницу - но с другими рядами (чьи термины становятся очень маленькими очень быстрыми) это предложение может быть действительно важным.
5 голосов
/ 16 сентября 2011

куча ошибок я замечаю ....

(1) Второе сканирование, вы помещаете значение в p, но никогда не используете p. Следовательно, вы будете проверять i <= v для v <= 0, поэтому «цикл» (см. Далее) не будет выполняться </p>

(2) вы используете 'while', когда вы должны использовать 'for' в своих циклах

(3) i - целое число, поэтому 1 / i будет равно 1 (для i = 1) или 0. Сделайте 1 / ((double) i) или что-то подобное.

Там может быть больше.

4 голосов
/ 16 сентября 2011

Сообщение об ошибке мало что говорит. Просто мне нужно было ")" перед ";" что я был уверен, что я имел право.

Сообщения об ошибках также сообщают, какая строка файла вызвала проблему. Вы можете использовать эту информацию, чтобы отследить проблему до подозрительных while операторов, которые должны использовать for вместо.

В вашем случае, как отмечали другие, вы хотите for (...;...;...) вместо while (...;...;...). Компилятор читает ваш исходный код слева направо, за один проход *; когда он достигает while, он ожидает, что ** увидит while (...), поэтому, как только он увидит while (...;, ; помечается как ошибка. Обратите внимание, что (и я уверен, вы понимаете, почему), просто добавив ) перед ;, вы не решите проблему в целом;)

* Это не требуется, но, по крайней мере, раньше это было проще, и есть вещи, которые являются ошибками в языке именно потому, что это позволяло компиляторам делать это таким образом. Вы должны помнить, что язык Си датируется началом 1970-х годов. В то время компьютеры были НАМНОГО менее мощными, поэтому языки программирования часто облегчали работу компилятора за счет программиста.

** Это, конечно, грубое упрощение, игнорирование деталей интерпретации части ....

2 голосов
/ 16 сентября 2011

Вы используете синтаксис цикла for в циклах while:

while (i=1; i<=v; i++) {

(или наоборот)

Попробуйте изменить это на:

for (i=1; i<=v; i++) {

Кроме того, 1/i всегда будет выдавать 0 в качестве ответа (поскольку они являются целыми числами), попробуйте 1.0/i.

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

1 голос
/ 16 сентября 2011
while (i=1; i<=v; i++) {

?

Может быть, вы хотите использовать для цикла?

for (i=1; i<=v; i++) {
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...