Различия в функциях 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()
также использует радианы.