【问题标题】:How i can make matlab precision to be the same as in c++?如何使 matlab 精度与 c++ 中的相同?
【发布时间】:2011-10-11 16:59:53
【问题描述】:

我的精度有问题。我必须使我的 c++ 代码具有与 matlab 相同的精度。在 matlab 中,我有一些用数字等做一些事情的脚本。我用 c++ 编写了与该脚本相同的代码。相同输入上的输出不同:(我发现在我的脚本中,当我尝试 104 >= 104 时它返回 false。我尝试使用长格式,但它并没有帮助我找出为什么它是错误的。这两个数字都是双倍。我想也许matlab在某个地方存储了104的真实值,它的真实值就像103.9999 ......所以我在c++中提高了我的精度。它也没有帮助,因为当matlab在c++中返回我的值50.000时,我得到了50.050 精度高。这两个值来自 + 或 * 等少数计算。有什么方法可以让我的 c++ 和 matlab 脚本具有相同的精度?

for i = 1:neighbors
  y = spoints(i,1)+origy;
  x = spoints(i,2)+origx;
  % Calculate floors, ceils and rounds for the x and y.
  fy = floor(y); cy = ceil(y); ry = round(y);
  fx = floor(x); cx = ceil(x); rx = round(x);
  % Check if interpolation is needed.
  if (abs(x - rx) < 1e-6) && (abs(y - ry) < 1e-6)
    % Interpolation is not needed, use original datatypes
    N = image(ry:ry+dy,rx:rx+dx);
    D = N >= C; 
  else
    % Interpolation needed, use double type images 
    ty = y - fy;
    tx = x - fx;

    % Calculate the interpolation weights.
    w1 = (1 - tx) * (1 - ty);
    w2 =      tx  * (1  - ty);
    w3 = (1  - tx) *   ty ;
    w4 =      tx  *    ty ;

    %Compute interpolated pixel values
    N = w1*d_image(fy:fy+dy,fx:fx+dx) + w2*d_image(fy:fy+dy,cx:cx+dx) + ...
    w3*d_image(cy:cy+dy,fx:fx+dx) + w4*d_image(cy:cy+dy,cx:cx+dx);

    D = N >= d_C; 

 end  

我在第 12 行的 else 中遇到了问题。tx 和 ty 等于 0.707106781186547 或 1 - 0.707106781186547。 d_image 的值在 0 和 255 之间。N 是从图像中插入 4 个像素的值 0..255。 d_C 的值为 0.255。仍然不知道为什么 matlab 显示当我有 N 个变量时,例如:x x x 140.0000 140.0000 和 d_C:x x x 140 x。 D 在第 4 位给我 0 所以 140.0000 != 140。我调试​​它尝试更精确,但它仍然说它的 140.00000000000000 并且它仍然不是 140。

int Codes::Interpolation( Point_<int> point, Point_<int> center , Mat *mat)
{


int x = center.x-point.x;
int y = center.y-point.y;

Point_<double> my;
if(x<0)
{
    if(y<0)
    {
        my.x=center.x+LEN;
        my.y=center.y+LEN;
    }   
    else
    {
        my.x=center.x+LEN;
        my.y=center.y-LEN;
    }

}
else
{
    if(y<0)
    {
        my.x=center.x-LEN;
        my.y=center.y+LEN;
    }   
    else
    {
        my.x=center.x-LEN;
        my.y=center.y-LEN;
    }
}


int a=my.x; 
int b=my.y;

double tx = my.x - a;
double ty = my.y - b;


double wage[4];
wage[0] = (1 - tx) * (1 - ty);
wage[1] =      tx  * (1 - ty);
wage[2] = (1 - tx) *      ty ;
wage[3] =      tx  *      ty ;



int values[4];

//wpisanie do tablicy 4 pixeli ktore wchodza do interpolacji
for(int i=0;i<4;i++)
{
    int val = mat->at<uchar>(Point_<int>(a+help[i].x,a+help[i].y));

    values[i]=val;
}




double moze = (wage[0]) * (values[0])  + (wage[1]) * (values[1]) + (wage[2]) * (values[2])  + (wage[3]) * (values[3]);
return moze;
}

LEN = 0.707106781186547 数组值中的值与 matlab 值 100% 相同。

【问题讨论】:

  • 您是说在 Matlab 和 C++ 中执行相同的计算集,在相同的double 输入上,产生不同的结果?如果是这样,请在 Matlab 和 C++ 中发布您正在执行的计算。
  • 你的问题不是你想的那样。
  • 104&gt;=104 在所有已知的编程系统中总是正确的。你没有告诉我们真实的故事。除非你能找出一些准确的细节,否则你就是在浪费我们(和你自己)的时间。
  • @DavidHeffernan 我认为他只是认为这是 104。104.000 &gt;= 104.0000001 是错误的,但 matlab disp 两个数字相同。

标签: c++ matlab precision


【解决方案1】:

Matlab 使用双精度。您可以使用 C++ 的 double 类型。这应该使大多数事情相似,但不是 100%。 正如其他人所指出的,这可能不是您问题的根源。要么算法有所不同,要么可能类似于在 Matlab 和 C++ 中定义不同的库函数。例如,Matlab 的 std() 除以 (n-1),您的代码可能会除以 n。

【讨论】:

  • C++库中有标准差函数吗?
【解决方案2】:

首先,根据经验,直接比较浮点变量绝不是一个好主意。而不是,例如,而不是 if (nr &gt;= 104),您应该使用 if (nr &gt;= 104-e),其中 e 是一个小数字,例如 0.00001

但是,您的脚本中一定存在一些严重的欠采样或舍入错误,因为得到 50050 而不是 50000 超出了常见浮点不精度的限制。例如,Matlab 的步长可以小至 15 位!

我猜你的代码中有一些转换问题,例如

int i;
double d;
// ...
d = i/3 * d;

将给出一个非常不准确的结果,因为你有一个整数除法。 d = (double)i/3 * dd = i/3. * d 会给出更准确的结果。

上面的例子在Matlab中不会造成任何问题,因为默认情况下所有的东西都已经是浮点数,所以c++和Matlab代码的结果差异可能是类似的问题。

查看您的计算将有助于找出问题所在。

编辑: 在 c 和 c++ 中,如果将 double 与具有相同值的整数进行比较,则它们很可能不相等。两个双打也是一样的,但是如果你对它们执行完全相同的计算,你可能会很幸运。即使在 Matlab 中它也很危险,也许你很幸运,因为两者都是双精度数,都以相同的方式被截断。 通过您最近的编辑看来,问题在于您评估阵列的位置。在比较 c++ 中的浮点数或双精度数时(或者在使用浮点变量时的任何语言中),您永远不应该使用 == 或 !=。进行比较的正确方法是检查它们是否彼此相距很小。

举个例子:使用 == 或 != 来比较两个 double 就像通过计算两个对象的原子数来比较两个对象的重量,并确定它们不相等,即使它们之间只有一个原子差.

【讨论】:

    【解决方案3】:

    除非您另有说明,否则 MATLAB 使用双精度。您在 C++ 中看到相同实现的任何差异都将是由于浮点错误。

    【讨论】:

      猜你喜欢
      • 2013-09-23
      • 2011-03-13
      • 1970-01-01
      • 1970-01-01
      • 2015-10-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-06-24
      相关资源
      最近更新 更多