C#双重加法-奇怪的行为 publicstaticvoidmain() { 字典值=新字典(); 添加(“a”,0.002); 添加(“b”,0.003); 添加(“c”,0.012); //迭代求和。 双v1=615.0; foreach(值中的KeyValuePair kp) { v1+=kp.值; } 控制台写入线(v1); //使用Sum方法求和。 双v2=615.0; v2+=values.values.Sum(); 控制台写入线(v2); Console.ReadLine(); }
当我在调试器中查看v1的值时,它给出的值为615.01699999994,但对于v2,它给出的值为615.017。出于某种原因,Sum方法会产生准确的结果,而迭代求和则不会。(当我打印这两个值时,它们是相同的,但我认为这是由于WriteLine方法所做的一些舍入。)C#双重加法-奇怪的行为 publicstaticvoidmain() { 字典值=新字典(); 添加(“a”,0.002); 添加(“b”,0.003); 添加(“c”,0.012); //迭代求和。 双v1=615.0; foreach(值中的KeyValuePair kp) { v1+=kp.值; } 控制台写入线(v1); //使用Sum方法求和。 双v2=615.0; v2+=values.values.Sum(); 控制台写入线(v2); Console.ReadLine(); },c#,math,c#-4.0,double,addition,C#,Math,C# 4.0,Double,Addition,当我在调试器中查看v1的值时,它给出的值为615.01699999994,但对于v2,它给出的值为615.017。出于某种原因,Sum方法会产生准确的结果,而迭代求和则不会。(当我打印这两个值时,它们是相同的,但我认为这是由于WriteLine方法所做的一些舍入。) 有人知道这里发生了什么吗?浮点数学天生就不是100%精确的,而且有错误。不同数字相加的顺序可能会影响浮点错误的大小。如果这些计算完全准确很重要,那么应该使用十进制,而不是双精度 这与使用求和与手动求和数据无关。在第一个过程中,你将每
有人知道这里发生了什么吗?浮点数学天生就不是100%精确的,而且有错误。不同数字相加的顺序可能会影响浮点错误的大小。如果这些计算完全准确很重要,那么应该使用十进制,而不是双精度
这与使用求和与手动求和数据无关。在第一个过程中,你将每个数字添加到615,在第二个过程中,你将所有数字相互添加,然后将它们添加到615。这是添加相同数据的不同顺序。根据您使用的数字,两种方法都可能导致或多或少的错误。双精度/浮点数的问题在于它们是二进制数,内部称为1000110.10101001,因此仅表示您的值的近似表示
阅读Jon Skeet的解释:这与使用双精度而不是十进制有关。浮点算术不是很好吗?看看这个话题,因为我想你会在那里找到一个好答案:。@TheBoss看到了同样的效果
double d1=615.0+(0.002+0.003+0.012);双d2=615.0+0.002+0.003+0.012那么,有没有办法知道它们的求和顺序,从而使浮点误差最小?不幸的是,decimal类型也不准确,不是针对上面的示例,而是针对我正在制作的程序。它确实不那么准确,但不如求和法准确。@BOSS:有没有办法知道它们必须按什么顺序求和,以使误差最小?对如果你正在进行大量的计算,并且需要能够估计误差范围或将其最小化,那么我建议你学习一门本科水平的数值方法课程,或者获取这门课程的教科书并学习它。作为一个粗略的经验法则:先把小东西加在一起。这并不能保证误差最小化,但它是一个很好的一次近似值。十进制同样“不准确”。浮点和十进制都更适合于某些类型的任务,但两者都不比另一种更精确。@phoog我指的是给出的示例数字,而不是一般的数字。另一位回答者已经链接到了对各种类型的讨论,OP说,由于没有发布在这里的代码中存在问题,十进制无法工作,因此我没有费心详细讨论它。小数和整数也是内部用1和0表示的二进制数;关键的区别在于小数使用以10为基数的系统来表示分数,而浮点数和双精度数使用以2为基数的系统。
public static void Main()
{
Dictionary<string, double> values = new Dictionary<string, double>();
values.Add("a", 0.002);
values.Add("b", 0.003);
values.Add("c", 0.012);
// Summing iteratively.
double v1 = 615.0;
foreach (KeyValuePair<string, double> kp in values)
{
v1 += kp.Value;
}
Console.WriteLine(v1);
// Summing using the Sum method.
double v2 = 615.0;
v2 += values.Values.Sum();
Console.WriteLine(v2);
Console.ReadLine();
}