C# 错误的减法?12.345 - 12 = 0.345000000000001

C# 错误的减法?12.345 - 12 = 0.345000000000001,c#,numbers,floating-point,floating-accuracy,subtraction,C#,Numbers,Floating Point,Floating Accuracy,Subtraction,我是C#的初学者,我正在研究浮点数。我需要在这两个数字之间做减法,但它不起作用。我知道这是由浮点数引起的,但我怎样才能修复它呢?如果你这么好,你能解释一下为什么会发生这种情况吗?提前谢谢。你的计算准确吗 float a = 12.35F; float b = 12.0F; float ans = a - b; //0.350000381 double x = 12.35; double y = 12.0;

我是C#的初学者,我正在研究浮点数。我需要在这两个数字之间做减法,但它不起作用。我知道这是由浮点数引起的,但我怎样才能修复它呢?如果你这么好,你能解释一下为什么会发生这种情况吗?提前谢谢。

你的计算准确吗

        float a = 12.35F;
        float b = 12.0F;
        float ans = a - b; //0.350000381

        double x = 12.35;
        double y = 12.0;
        double ans2 = x - y; //0.34999999999999964

        decimal n = 12.35m;
        decimal m = 12.0m;
        decimal ans3 = n - m; //0.35

对我来说,这些计算给出了正确的结果。

考虑使用十进制而不是浮点:

// Instead of this...
float a = 12.345F;
float b = 12;
float c = a - b;

// Use this: 
decimal d = 12.345M;
decimal e = 12;
decimal f = d - e;

Jon Skeet在这个答案中很好地解释了这两种类型之间的差异:

取决于您可以使用十进制类型,或者按原样存储,但是在显示答案之前,请记住浮点的行为可能会因您使用的处理器而异

这个论坛上的一个问题是关于这个主题的

如果你真的想深入研究这个主题,这是一个关于如何检查浮点运算行为的好资料。这不是一个c问题,这是一个计算机科学问题。如果你想真正了解正在发生的事情,请阅读。如果你只是关心为什么会有这个问题,那是因为在这个平台上Float和Double分别精确到7和15位,你需要应用舍入逻辑来实现你想要的结果

将无穷多个实数压缩为有限位数 需要近似表示。虽然有无限的 许多整数,在大多数程序中,整数计算的结果可以 存储在32位中。相反,给定任何固定的位数, 大多数实数计算会产生 无法使用那么多位精确表示。因此 浮点计算的结果通常必须按顺序四舍五入 以适应它的有限表示。这个舍入误差是最大的 浮点运算的特点


请把你的密码寄出去。所有的变量都是浮动的吗?你能发布代码吗?你题目中的计算看起来很奇怪。正常的浮点舍入不会导致这种行为。一些演示问题的代码会有所帮助。发布完整的代码,即使有舍入错误和浮点数据,您也无法从这些输入中获得结果。您确定答案是0.000000000000001而不是0.345000000000001吗?后者我可以解释+1:如果你需要任何类型的数字保真度,
decimal
是最好的选择。decimal就是我想要的,非常感谢。我还要感谢那些解释了为什么会发生这种事的人。这取决于这些数字的用途。您应该始终使用
十进制
表示货币。但不适用于物理模拟。即使完全相同的问题不会发生在
十进制
中,但如果从该数字中减去一个数字的最重要部分(如整数部分),结果的精度仍然是有限的。例如,让
十进制g=10000000000000000m/7m;十进制h=142857142857142857m;小数i=g-hi
最多只能精确到11位;我以为十进制的精度是28到29位?因此,十进制仍然会丢失精度。很高兴找到人,他说这是一个明显的问题,而且这肯定是编程中的一个bug(问题),尚未解决。即使是我的旧计算器也工作得很好,现在已经是2019年了,我们在个人电脑方面仍然很头疼。