为什么c#不能做任何确切的操作.
Math.Pow(Math.Sqrt(2.0),2) == 2.0000000000000004
Run Code Online (Sandbox Code Playgroud)
我知道双打是如何工作的,我知道舍入误差来自哪里,我知道它几乎是正确的值,而且我知道你不能在有限的双精度中存储无限数.但是为什么没有一种方法可以让c#完全计算出来,而我的计算器可以做到.
编辑
这不是我的计算器,我只是举个例子:
干杯
我试图将浮动显示只有一个小数点.我得到了意想不到的结果如下:
码:
float a = 1.25;
float b = 1.35;
NSLog(@"1.25 -> %.1f\n1.35 -> %.1f",a,b);
Run Code Online (Sandbox Code Playgroud)
输出:
1.25 - > 1.2
1.35 - > 1.4
预期产出,或者:
1.25 - > 1.3
1.35 - > 1.4
要么:
1.25 - > 1.2
1.35 - > 1.3
这仅仅是由于二进制和十进制之间的内部转换?如果是这样,我如何获得预期的行为?
我正在使用Xcode 4.6.
编辑:好的,感谢TonyK和H2CO3,这是由于小数的二进制表示.
float a = 1.25;
float b = 1.35;
NSLog(@"1.25 -> %.30f\n1.35 -> %.30f",a,b);
Run Code Online (Sandbox Code Playgroud)
1.25 - > 1.250000000000000000000000000000
1.35 - > 1.350000000000000088817841970013
很多好消息,但据我所知,没有人接近第二个问题:我如何得到预期的行为?
Objective-C中的舍入数字是一个完全不同的问题.
我正在搞乱傅立叶变换.现在我已经创建了一个实现DFT实现的类(没有像FFT atm这样做).这是我用过的实现:
public static Complex[] Dft(double[] data)
{
int length = data.Length;
Complex[] result = new Complex[length];
for (int k = 1; k <= length; k++)
{
Complex c = Complex.Zero;
for (int n = 1; n <= length; n++)
{
c += Complex.FromPolarCoordinates(data[n-1], (-2 * Math.PI * n * k) / length);
}
result[k-1] = 1 / Math.Sqrt(length) * c;
}
return result;
}
Run Code Online (Sandbox Code Playgroud)
这些是我得到的结果 Dft({2,3,4})

好吧,看起来还不错,因为那些是我期望的值.我发现只有一件事令人困惑.这一切都与双打的四舍五入有关.
首先,为什么前两个数字不完全相同(0,8660..443 8)vs(0,8660..443).为什么它不能计算零,你期望它.我知道2.8E-15非常接近于零,但事实并非如此.
任何人都知道这些,边缘的错误是如何发生的,如果我能够并且想要对它做些什么.
似乎没有真正的问题,因为它只是小错误.但是,如果您要比较2个值,那么如何处理这些舍入误差.
5,2 + 0i != 5,1961524 …Run Code Online (Sandbox Code Playgroud)