1

我知道在现代计算机系统中执行的浮点运算并不总是与实际运算一致。我正在尝试设计一个小型 C# 程序来演示这一点。例如:

static void Main(string[] args)
    {
        double x = 0, y = 0;

        x += 20013.8;
        x += 20012.7;

        y += 10016.4;
        y += 30010.1;

        Console.WriteLine("Result: "+ x + " " + y + " " + (x==y));
        Console.Write("Press any key to continue . . . "); Console.ReadKey(true);
    }

但是,在这种情况下,xy到底是相等的。

我是否可以使用类似复杂性的程序来证明浮点运算的不一致性,而不使用任何真正疯狂的数字?如果可能的话,我想避免数学上正确的值超过小数点几位。

4

9 回答 9

5
double x = (0.1 * 3) / 3;
Console.WriteLine("x: {0}", x); // prints "x: 0.1"
Console.WriteLine("x == 0.1: {0}", x == 0.1); // prints "x == 0.1: False"

备注:基于此,不要假设浮点运算在 .NET 中不可靠。

于 2010-04-15T17:19:03.260 回答
2

这是一个基于先前问题的示例,该示例演示了浮点算术与您想象的完全不一样。

float f = (13.45f * 20);
int x = (int)f;
int y = (int)(13.45f * 20);
Console.WriteLine(x == y);

在这种情况下,false打印到屏幕上。为什么?因为执行数学运算的位置与发生转换为 int 的位置。对于 x,在一个语句中执行数学运算并存储到 f,然后将其转换为整数。对于 y,计算的值永远不会在转换之前存储。(在 x 中,在计算和强制转换之间会丢失一些精度,而不是 y。

有关浮点数学中具体发生的事情背后的解释,请参阅此问题/答案。为什么用括号分隔和用语句分隔时 C# 中的浮点精度不同?

于 2010-04-15T17:28:39.357 回答
2

我最喜欢的演示归结为

double d = 0.1;
d += 0.2;
d -= 0.3;

Console.WriteLine(d);

输出不是 0

于 2010-04-15T17:41:42.677 回答
1

试着让它小数点不是 0.5。

看看这篇文章在这里

http://floating-point-gui.de/

于 2010-04-15T17:16:59.583 回答
0

尝试总和非常大和非常小的数字。小的将被消耗,结果将与大数相同。

于 2010-04-15T17:18:51.290 回答
0

尝试对无理数(例如平方根)或非常长的重复分数执行重复运算。您会很快看到错误累积。例如,计算 1000000*Sqrt(2) 与 Sqrt(2)+Sqrt(2)+...+Sqrt(2)。

于 2010-04-15T17:19:48.347 回答
0

我现在能想到的最简单的是:

class Test
{
    private static void Main()
    {
        double x = 0.0;

        for (int i = 0; i < 10; ++i)
            x += 0.1;

        Console.WriteLine("x = {0}, expected x = {1}, x == 1.0 is {2}", x, 1.0, x == 1.0);
        Console.WriteLine("Allowing for a small error: x == 1.0 is {0}", Math.Abs(x - 1.0) < 0.001);
    }
}
于 2010-04-15T17:24:43.567 回答
0

我建议,如果你真的感兴趣,你可以看看任何一个讨论浮点数的页面,其中一些非常详细。您很快就会意识到,在计算机中,它们是一种妥协,以精度换取范围。如果您要编写使用它们的程序,您确实需要了解它们的局限性和如果您不注意可能出现的问题。这将是值得您花时间的。

于 2010-04-15T17:26:45.770 回答
-1

double精确到约 15 位数字。您需要更高的精度才能真正开始只用几个浮点运算来解决问题。

于 2010-04-15T17:19:37.160 回答