Различия в функциях Matlab Cosine и C Cosine

У меня есть формула, которую я реализовал в C, я сделал это, но результат, который я получаю, отличается от Matlab

код:

  double sumVector(float x[], int M){


        double y = 0;
        int i;

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


            y += (0.5*x[i]) + ((x[i])*(x[i])* (cos(floor(x[i]/4) - 32)));


        }

        return y;
    }

Где x[] - массив с элементами 0:0.001:255

Результат в C равен 37022697,82 Результат в Matlab равен -12767828,5

Почему существует такой большой разброс и чем это вызвано?

заранее спасибо

2 ответа

Я думаю, вы имеете в виду, что ваш массив x[] содержит элементы 0.0, 0.001, 0.002 ... 255.0. Это верно?

С этим допущением, следующий код C дает -12767828.504138, что согласуется с вашим результатом MATLAB (в пределах числовой точности). Как указано в комментариях, вы должны быть осторожны с float а также doubleи, вероятно, вы хотите, чтобы ваша функция перебирала все элементы x, включая x[0]. Кроме того, я не знаю, как вы инициализируете свой массив и как вы вызываете функцию.

#include <math.h>
#include <stdio.h>
#include <stdlib.h>

double sumVector(double x[], int M){


  double y = 0.0;
  int i;

  for(i = 0; i<M ; i++){


    y += (0.5*x[i]) + ((x[i])*(x[i])* (cos(floor(x[i]/4.0) - 32.0)));


  }

  return y;
}

int main()
{
  const int M = 255001;
  const double delta = 0.001;
  double *x = malloc(M * sizeof(double));
  int i;

  // Fill the array. Is that what you want?
  for(i = 0; i < M; i++) {
    x[i] = i * delta;
  }

  printf("Result = %f\n", sumVector(x, M));

  free(x);

  return 0;
}

У @WeatherVane и @TroyHaskin есть ответ на ваш вопрос в комментариях: вы, вероятно, неправильно выполняете итерацию по вашему массиву, поэтому ваш векторный расчет в C, вероятно, не тот, который вы хотите. (Мы можем только предполагать, что ваша реализация Matlab верна.)

В C индексы массива начинаются с 0, а не с 1. Мы можем только предполагать, что M количество элементов в массиве x и что вы действительно хотели включить все M элементы в вашем for петля. Итак, элементы x диапазон от x[0] через x[M-1], В вашем коде вы не включаете первый элемент x[0] в вашем расчете. Попробуйте это вместо этого:

double sumVector(double x[], int M) {
  double y = 0.0;
  int i;

  for(i=0; i<M; i++){
    y += 0.5*x[i] + x[i]*x[i]*cos(floor(x[i]/4.0) - 32.0));
  }
  return y;
}

Обратите внимание, что я изменил тип вашего x к массиву double, В Matlab, double точность по умолчанию для чисел с плавающей запятой. Подумайте, как и в случае с C:doubleесли вы действительно не знаете, что делаете.

это i=0; i<MAX; i++Формат является обычной практикой в ​​C. Привыкнуть к нему. Это должно выглядеть странно, чтобы начатьi=1или проверитьi<=MAX, (Это не значит, что это обязательно неправильно, но это должно бросаться в глаза.)

Кроме того, комментарий @Olaf предупреждает вас об осторожности при делении на C. Если оба операнда имеют целочисленный тип, он выполнит целочисленное деление. Если вы используете, например, 1.0 вместо 1, это вызывает деление с плавающей запятой. Это также делает читателя более понятным, что вы используете константы с плавающей запятой вместо целочисленных констант.

В Matlab,cos принимает радианы и библиотеку Ccos() также использует радианы.

Другие вопросы по тегам