如何计算C#中非常大的double数组的舍入

时间:2013-11-27 17:44:29

标签: c# arrays double rounding

在C#中我有一个double数组(double[]我的意思是) 我想将所有值四舍五入到C#中的两位小数。

一种解决方案是使用foreach()Math.Round()函数执行此操作 但阵列非常大(1.000.000到10.000.000值)

而不是foreach,是否有更有效的解决方案?

6 个答案:

答案 0 :(得分:8)

  

而不是foreach,更有效的解决方案?

不。从根本上说,如果要舍入所有值,则必须舍入所有值。没有任何魔法可以使这更简单。

当然,如果您只是要访问一些值,那么您可能会重新设计代码以懒惰访问 - 甚至是显示 - 但如果您确实需要所有值的舍入版本,没有什么能比O(n)操作更快。

你可以按照其他答案中的说法并行执行,这可能会使更快 - 但它会同时比单线程方法更少效率。 (由于所涉及的协调,你最终会做更多的工作 - 但你可能仍然可以更快地完成它。)

您还没有说过为什么要对这些值进行舍入 - 通常,您应该只在显示点处舍入值。你真的确定在此之前需要绕过它们吗?这些价值代表什么? (如果它们是财务价值,您应该强烈考虑decimal而不是double。)

答案 1 :(得分:3)

您可以尝试Parallel.Foreach并将其设为

虽然每个项目仍有操作,但操作不是原子操作,所以你可以这样做。

答案 2 :(得分:2)

我认为没有任何解决方案不包含某种循环。你可以使用LINQ:

array = array.Select(v => Math.Round(v, 2)).ToArray();

但它会比你的自定义for循环更慢,因为它不会修改数组,而是创建一个带有新值的新数组。

为了让你的循环更快,你可以将它分成几部分并使用TPL同时运行。

答案 3 :(得分:2)

以多线程方式执行此操作:

Parallel.For(0, arr.Length, i => arr[i] = Math.Round(arr[i], 2));

答案 4 :(得分:0)

任何解决方案最终都会转变为循环。虽然你可以很好地写出Linq声明:

rounds = mean.Select(x=>Math.Round(x,2));

如果您有多个处理器,那么可能更快的解决方案是使用Parallel.Foreach,但您必须对其进行测试以确定它是否确实存在。

答案 5 :(得分:0)

是的,您可以使用Parallel.ForEach

List<Double> values;
//fill list

ConcurrentBag<Double> rounded = new ConcurrentBag<Double>();

Parallel.ForEach(
  values,
  value =>
  {    
    rounded.Add(/*value rounded to 2 decimal places*/);
  });