1

我一直在尝试将一些 MATLAB 代码翻译成 C,但一个特定的函数在两种语言之间给了我不同的结果。我不认为这是一个精度错误,因为变量的值并没有大得惊人或小得惊人。我将不时发布代码,然后提供有关变量值的信息:

Preproccesor 指令(此文件已链接):

#include "ff_addfunc.h"
#include <stdio.h>
#include <stdlib.h>
//#include <complex.h> (already included in the header file)
#include <math.h>
#ifndef HBAR
#define HBAR 1
#endif
#ifndef SPRING_CONST
#define SPRING_CONST 1
#endif
#ifndef PI
#define PI 3.14159265359
#endif

下面是 C 中的问题函数,下面是 MATLAB 中的相同函数。在调用此函数之前,两者之间的所有数值结果都匹配。我发现什么时候x1 == x2,MATLAB 和 C 就结果达成一致;但是当 时x1 != x2,C 返回一个稍微不同的结果,我将在下面展示。这意味着减号左边的算术导致了问题。

这是C代码:

double lagrangian(double x1,double x2,double dt,double m) {
    return 1/2*m*(x2-x1)*(x2-x1)/dt/dt-SPRING_CONST*(x2*x2+x1*x1)/4;
}

这是 MATLAB 等价物:

function L = Lagrangian(x1,x2,dt,m)

k = 1;
L = 1/2*m*(x2-x1).^2./dt.^2-k*(x2.^2+x1.^2)/4;

我发现如果我有x1 = -4, x2 = -3.986667, dt = 0.049087, 并且m = 1C 函数返回-7.973378而 MATLAB 给了我-7.9365. 现在,我之所以将其作为 C 而不是 MATLAB 中的问题,是因为我能够使用 google 作为计算器来验证 MATLAB 编号。

我使用 gcc 编译,因为 g++ 抱怨我使用#include<complex.h>而不是#include<complex>.

谁能告诉我这是为什么以及如何纠正它?如果有任何问题或需要查看更多代码,请告诉我。

其他说明(没有导致更改):

  • 我在 linux 和 OS X(两个不同的系统)上试过这个
  • 试过pow()而不是(x2-x1)*(x2-x1)
  • 将数字直接放入 C 和 MATLAB 函数中,以说明我打印出的显示数字中的任何四舍五入
  • 打印出每个输入以确保它们相同并检查是否使用了正确的数据类型
4

3 回答 3

1

我用了:

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#ifndef HBAR
#define HBAR 1.0
#endif
#ifndef SPRING_CONST
#define SPRING_CONST 1.0
#endif
#ifndef PI
#define PI 3.14159265359
#endif

double lagrangian(double x1,double x2,double dt,double m) {
    return 1.0/2.0*m*(x2-x1)*(x2-x1)/dt/dt-SPRING_CONST*(x2*x2+x1*x1)/4.0;
}

int
main(void)
{
    printf("l: %g\n", lagrangian(-4,-3.986667,0.049087,1));
    return 0;
}

并得到:

l: -7.93649

我认为你的非常double数正在搞砸你的计算。实际上只是更换

1.0/2.0*m...

1/2*m...

为我复制了你的错误价值。

于 2013-05-22T05:05:27.267 回答
1

在 C 中,/具有*相同的优先级并从左到右关联。这意味着在这个子表达式中:

1/2*m*(x2-x1)*(x2-x1)/dt/dt

子表达式1/2被分组。因为12都是int常量,所以这是一个整数除法——它是截断的。 1/2在 C 中总是为零,所以整个子表达式都为零。

使用1.0/2.0(或只是0.5)代替。

于 2013-05-22T05:08:58.953 回答
1

直接翻译是:

0.5*m*(x2-x1)*(x2-x1)/(dt*dt)-SPRING_CONST*(x2*x2+x1*x1)/4;

(固定整数除法和dt术语分组)

于 2013-05-22T05:10:40.267 回答