如何将双精度舍入到预定义列表中最接近的最高值?

时间:2014-11-18 09:51:34

标签: c# rounding

第一个问题在这里看了一会儿,没有运气。 该程序的这一部分的目的是将值> = 1且<10的值舍入到下面列表中的下一个最高值。 将被舍入的列表的示例是:

var preferredValuesList = new List<double> { 1.0, 1.1, 1.2, 1.3, 1.5, 1.6,  
                                             1.8, 2.0, 2.2, 2.4, 2.7, 3.0,
                                             3.3, 3.6, 3.9, 4.3, 4.7, 5.1,
                                             5.6, 6.2, 6.8, 7.5, 8.2, 9.1};

例如,对于值2.1应该向上舍入到2.2。值2.4应保持在2.4

我现在从另一个问题这样做的方法如下:

double preferredResistance = 
preferredValuesList.OrderBy(item => Math.Abs(tempResistance - item)).First();

我已经听说过使用循环进行舍入,但我相当新,并且不明白我将如何做。

感谢你们给予的任何帮助。

3 个答案:

答案 0 :(得分:4)

您可以将linq用于此查询:

double value = 2.1;
double roundedValue = preferredValuesList.OrderBy(x=>x).FirstOrDefault(x=> x>= value);

它的作用是返回preferredValuesList中的第一个值,该值大于或等于未舍入值。这正是你想要的。

您提到的First方法Returns the first element in a sequence that satisfies a specified condition.(来自Documentation)。此示例中的条件为x >= value

方法FirstOrDefault执行相同的操作,只是如果没有找到任何元素而不是抛出异常,它将返回默认值(如果是double列表,则返回0)。

注意.OrderBy(x=>x)仅用于确保您的列表已订购(例如,不是{3,7,5,1,9} ...)

答案 1 :(得分:3)

这避免了O(nlogn)排序:

double preferredResistance = tempResistance;
var greater = preferredValuesList.Where( item > tempResistance);
if (greater.Any())
    preferredResistance = greater.Min();

答案 2 :(得分:1)

由于您的列表是有序的,因此您可以进行二元搜索,效率最高。

如果值存在,它将返回它的索引,这意味着在您的情况下不需要舍入。否则,它将返回第一个元素的索引的按位补码,该索引高于您的项目。

简单来说,如果返回的值是正数,只需坚持你的数字即可。 否则,请获取列表中的数字,如下所示:

int index = preferredValuesList.BinarySearch(item);
double preferredResistance = index > 0 ? item : preferredValuesList.ElementAt(~index);

如果项目可能高于列表中的最大值,则应使用以下安全检查之一:

如果您希望该项目保持原样:

int index = preferredValuesList.BinarySearch(item);
double preferredResistance = index > 0 || ~index >= preferredValuesList.Count ?
item : preferredValuesList.ElementAt(~index);

如果您希望将项目向下舍入到列表中的最大值:

int index = preferredValuesList.BinarySearch(item);
double preferredResistance = index > 0 ? item :
preferredValuesList.ElementAt(Math.Min(~index, preferredValuesList.Count - 1));
相关问题