如何使用fmod并避免精度问题

时间:2015-02-26 08:14:12

标签: c precision modulus double-precision

我将这个问题归结为最简单的形式:

  

让我们以0.05的步长从[0 .. 5.0]迭代并打印出' X'   每0.25乘数。

for(double d=0.0; d<=5.0; d+=0.05) {
  if(fmod(d,0.25) is equal 0)
    print 'X';
}

这当然不起作用,因为d将是[0,0.0500000000001,0.100000000002,...]导致 fmod()失败。极端的例子是d=1.999999999998fmod(d,0.25) = 1

如何解决这个问题? Here is一个可编辑的在线示例。

2 个答案:

答案 0 :(得分:6)

我只是不以这种方式使用浮点变量来解决这个问题:

for (int i = 0; i <= 500; i += 5) {
  double d = i / 100.0;  // in case you need to use it.
  if ((i % 25) == 0)
    print 'X';
}

它们通常存在问题,因此在避免它们方面需要额外的努力。

答案 1 :(得分:2)

如果你总是有相同的固定小数,只需乘以你的循环计数器(在这种情况下乘以20)。如果要以double形式访问它,除以20.实际上,您使用隐藏指数将双精度值保持为整数。

在这个例子中,我使用一个整数作为循环计数器,假设它具有所需的精度。

for(int i=0; i<=100; i+=1) {
  if(i % 5 == 0)
    print 'X';
  double d = (double)i / 20.0;
  // use d
}