我有一个对象列表,我试图在多个 3 个字段之后对这些对象进行求和。问题是,当我按以下两种情况运行计算时,最终结果不匹配:
1 -purchasesDeserialized.Sum(reference => reference.Price * reference.Box * reference.Qty)
2 -purchasesDeserialized.OrderBy(r => r.Box).Sum(reference => reference.Price * reference.Box * reference.Qty);
两种情况下的数据是相同的,区别在于情况#1 中我不先排序而进行计算,而情况#2 中我先排序然后计算。(我预计结果是相同的,因为排序不应更改任何基础数据,而只是重新排序)。
不确定 LINQ 是否影响 OrderBy 之后的计算,或者问题是否出现在 C# 小数舍入方面。
完整复制代码:
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
namespace ConsoleApp1
{
public class Purchase
{
public decimal Price { get; set; }
public decimal Box { get; set; }
public decimal Qty { get; set; }
}
class Program
{
static void Main(string[] args)
{
string purchases = "[{\"Box\":10.0,\"Qty\":206.000000,\"Price\":8.323300970873786407766990292},{\"Box\":10.0,\"Qty\":108.000000,\"Price\":8.333333333333333333333333333},{\"Box\":10.0,\"Qty\":46.000000,\"Price\":8.695652173913043478260869565},{\"Box\":10.0,\"Qty\":18.000000,\"Price\":24.833333333333333333333333333},{\"Box\":1.0,\"Qty\":566.000000,\"Price\":80.87985865724381625441696112},{\"Box\":1.0,\"Qty\":12.000000,\"Price\":97.46666666666666666666666667},{\"Box\":1.0,\"Qty\":72.000000,\"Price\":103.06805555555555555555555556},{\"Box\":1.0,\"Qty\":246.000000,\"Price\":81.2906504065040650406504065},{\"Box\":1.0,\"Qty\":78.000000,\"Price\":80.08333333333333333333333333},{\"Box\":10.0,\"Qty\":146.000000,\"Price\":8.030821917808219178082191782},{\"Box\":10.0,\"Qty\":178.000000,\"Price\":8.326404494382022471910112359},{\"Box\":10.0,\"Qty\":364.000000,\"Price\":8.324175824175824175824175825},{\"Box\":10.0,\"Qty\":30.000000,\"Price\":8.666666666666666666666666667},{\"Box\":10.0,\"Qty\":36.000000,\"Price\":24.5000000000000000000},{\"Box\":1.0,\"Qty\":120.000000,\"Price\":83.662500000000000000},{\"Box\":1.0,\"Qty\":332.000000,\"Price\":80.74698795180722891566265061},{\"Box\":1.0,\"Qty\":36.000000,\"Price\":78.833333333333333333333333333},{\"Box\":1.0,\"Qty\":22.000000,\"Price\":96.35909090909090909090909091},{\"Box\":1.0,\"Qty\":134.000000,\"Price\":78.149253731343283582089552239},{\"Box\":10.0,\"Qty\":26.000000,\"Price\":24.346153846153846153846153846},{\"Box\":1.0,\"Qty\":298.000000,\"Price\":97.06644295302013422818791947},{\"Box\":1.0,\"Qty\":18.000000,\"Price\":95.22777777777777777777777778},{\"Box\":10.0,\"Qty\":6.000000,\"Price\":24.166666666666666666666666667},{\"Box\":1.0,\"Qty\":82.000000,\"Price\":96.42195121951219512195121951},{\"Box\":10.0,\"Qty\":154.000000,\"Price\":8.149350649350649350649350649}]";
var purchasesDeserialized = JsonConvert.DeserializeObject<List<Purchase>>(purchases);
var sumRes1 = purchasesDeserialized
.Sum(reference => reference.Price * reference.Box * reference.Qty);
Console.WriteLine("Sum:" + sumRes1); //returns 294648.40000000000000000000000M
var sumRes2 = purchasesDeserialized
.OrderBy(r => r.Box)
.Sum(reference => reference.Price * reference.Box * reference.Qty);
Console.WriteLine("Sum after sort:" + sumRes2); //returns 294648.39999999999999999999999M
}
}
}
Run Code Online (Sandbox Code Playgroud)
和输出:
Sum:294648.40000000000000000000000
Sum after sort:294648.39999999999999999999999
Run Code Online (Sandbox Code Playgroud)
小智 1
我认为问题在于您在增加总金额(在求和操作期间)的同时降低了小数最大精度。
在这种情况下,集合中元素的顺序很重要,因为它将影响超出小数精度的点。然后剩余的元素将被添加,但不精确,最终会导致不同的总数。
举个例子,假设我的数据类型最多可以容纳 4 个位置:
var x = 4.998;
var y = 0.002;
var z = 10.00;
x + y + z = 4.998 + 0.002 + 10.00 => 15.00;
z + x + y = 10.00 + 4.998 + 0.002 => 14.99; //(because 10.00 + 4.998 = 14.99 and there is no precision left for remaining decimal place, so its stripped)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1139 次 |
| 最近记录: |