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

本文关键字:舍入 最接近 高谷 双精度 预定义 列表 | 更新日期: 2023-09-27 18:30:51

环顾四周一段时间后没有运气后,第一个问题在这里。程序的这一部分目的是将>= 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();

我听说过使用循环进行舍入,但我相当新手,不明白我会怎么做。

感谢你们可以提供的任何帮助。

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

可以使用 linq 进行此查询:

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

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

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

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

注意.OrderBy(x=>x)只是为了确保您的列表是有序的(即不是{3,7,5,1,9}例如...

这避免了 O(nlogn) 排序:

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

由于您的列表是有序的,因此您可以执行 BinarySearch,这非常高效。

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

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

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));