Неточное среднее значение во время выполнения - PullRequest
0 голосов
/ 05 января 2019

Я пытаюсь решить проблему, и у меня возникла небольшая проблема.
Я должен найти скользящее среднее для ряда чисел.
Пример:

input 4 2 7 
output 4 3 4.3333

Теперь вот проблема, хотя я получаю ответ, это не точный ответ.

Принятый вывод: разница точности, показанная на изображении

 290.6666666667
 385.4000000000
 487.8333333333
 477.4285714286
 496.4444444444
 ...
 523.8571166992
 506.0454406738
 495.3043518066

Я не могу найти, что не так. Некоторая помощь будет высоко ценится.

#include<stdio.h>

main(){
  int n;
  printf("set:");
  scanf("%d",&n);
  float arr[n+1],resarr[n+1];
  float sum=0;

  for(int i=1; i<=n; i++){
    scanf("%f",&arr[i]);
    sum=arr[i]+sum;

    float res= sum/(float)i;
    resarr[i]=res;
  }
  int i=1;
  while(i<=n) {
    printf("%0.10f\n",resarr[i]);
    i++;
  }

  return 0;
}

Ответы [ 2 ]

0 голосов
/ 05 января 2019

Код не может достичь желаемой точности, так как он использует float вместо double. @ Какой-то программист, чувак

Типично float с точностью до 1 части в 2 23 . Для печати до 0.0000000001 лучше использовать double, что обычно с точностью до 1 части в 2 53 .

#include<stdio.h>

int main(void) {
  //float arr[n + 1], resarr[n + 1];
  //float sum = 0;
  double arr[n + 1], resarr[n + 1];
  double sum = 0;
  ...

    // scanf("%f", &arr[i]);
    scanf("%lf", &arr[i]);

    ...
    // float res = sum / (float) i;
    double res = sum / i;  // cast not needed as `sum` is `double`
  ...
}

Итерация с 1 не является идиоматической в ​​C. Более распространенная итерация, начиная с 0.

size_t лучше всего подходит для определения размера и индексации массива. int может быть слишком узким. Конечно, с небольшими массивами это мало что меняет.

#include<stdio.h>

int main(void) {
  printf("set:");
  size_t n;
  scanf("%zu", &n);
  double arr[n], resarr[n];
  double sum = 0;

  for (size_t i = 0; i < n; i++) {
    scanf("%lf", &arr[i]);
    sum = arr[i] + sum;

    double res = sum / (i+1);
    resarr[i] = res;
  }

  for (size_t i = 0; i < n; i++) {
    printf("%0.10f\n", resarr[i]);
  }

  return 0;
}

Более надежный код будет проверять ввод от пользователя, который гарантирует, что он действителен, распределять, а не использовать VLA, если n разрешено иметь большой размер, сбрасывать вывод перед чтением и т. Д.

Обратите внимание, что массив arr[] не нужен, просто один double для ввода и sum.

0 голосов
/ 05 января 2019

Здесь

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

вы пытаетесь получить доступ из связанных элементов массива, это, безусловно, вызывает неопределенное поведение , так что давайте предположим, что если n равно 5, то вы обращаетесь к arr[5], который также не существует.

C не выполняет проверку граничных условий массива, его обязанность программиста - не обращаться к связанным элементам, иначе это вызывает UB.

В C индекс массива начинается с 0, а не с 1. Так что лучше начните вращать петлю с 0 до n. Например,

for(int i=0; i<n; i++) { 
   scanf("%f",&arr[i]);
   /* some code */
}
...