c ++中的奇怪上限错误

时间:2013-03-08 10:20:04

标签: c++ floating-point ceiling

您好我在c ++中的ceil函数遇到了一些困难:

我有一个规则的点网格,我需要对它进行插值来计算一组点的z值。

为了做到这一点,我需要为每个计算点获得网格上最近的点。我是这样做的:

y1 = dy*floor(p.y/dy);
y2 = dy*ceil(p.y/dy);

其中dy是网格两点之间的空间。 (y1,p.y和dy是双倍的) 如果我使用

显示结果
cout << static_cast<double>(p.y/dy) << ": " << y1 << ", " << y2 << endl;

我得到了这些奇怪的结果:

0: 0, 0
1: 0.1, 0.1
2: 0.2, 0.2
3: 0.3, 0.4

三个第一个结果是可以的,但最后一个结果是错误的,并使断言失败。

我想知道这个奇怪的错误来自哪里以及如何避免它。 感谢。

我为我的英语道歉

修改

我用dy = 0.1调用函数,但在执行期间,它采用下面的值dy = 0.10000000000000001。 p.y初始化如下:

 const uint N = round((x2 - x1) / dx2);
 const uint M = round((y2 - y1) / dy2);

 double p = persistence;
 double n = number_of_octaves;

 // generation of the points where the perlin noise is generated
 std::vector<Vertex3d> ret;
 std::vector<Vertex3d> dummy;
 for (uint i=0;i<=N;++i)
 {
        for (uint j=0;j<=M;++j)
        {
                ret.push_back({.x = i*dx2, .y=j*dy2, .z=0});
                dummy.push_back({.x = i*dx2, .y=j*dy2, .z=0});
        }
 }

其中x1 = 0且x2 = 1(根据gdb)

3 个答案:

答案 0 :(得分:1)

当您使用浮点运算时,由于浮点计算不精确,通常不应该依赖结果为完整的整数。您可能需要重新设计代码,以便它不依赖于此。

这是classic discussion of floating point arithmetic

答案 1 :(得分:1)

根据您的结果,我认为dy等于0.1

你的结果没有错。如果您有0.3 < p.y < 0.4,那么您将3 < p.y/dy < 4,因此ceil将为4,而floor将为3

也许您感到困惑,因为代码中的其他地方您将p.y设置为0.3或0.4。您应该知道浮动不那么精确。这意味着,即使您设置了p.y = 0.3,它的值也可能为0.30000001或类似值,从而导致您的问题。

答案 2 :(得分:-1)

这看起来就像浮点运算的舍入错误一样。

可能是最后一种情况下的结果是3.00000000000001所以它的上限是4而不是3(然后乘以0.1)