【问题标题】:find smallest number closest to an integer in an array excel在数组excel中找到最接近整数的最小数字
【发布时间】:2020-03-06 05:56:38
【问题描述】:

我在 Excel 工作表中有一个动态值列表。我需要找到一种方法来识别数组中最接近整数的最小数字。 例子: 在一种情况下,该清单包括以下数字: 1.56、1.65、1.71、1.84、1.94、2.00、2.06、2.03、2.22............2.95、3.05、3.81、4.00 等 我想在这种情况下找到的数字是 2.00。 Excel 中是否有可以用于此目的的函数?

【问题讨论】:

  • 这个问题似乎根本没有包括任何解决问题的尝试。请编辑问题以显示您尝试过的内容,并使用Minimal, Complete, and Verifiable example 显示您遇到的特定障碍。欲了解更多信息,请参阅How to Ask
  • 你的列表总是排序的吗?
  • 为什么是 2? 4 也最接近整数。
  • 如果四舍五入 (2 & 4) 有平局,我认为 OP 想找到其中最低的 (2)

标签: excel excel-formula


【解决方案1】:

只是一个想法:

差异公式:

=ABS(IFERROR(MID($A2,1,FIND(".",$A2,1)-1),$A2)-$A2)

最小值的公式:

=INDEX($A$2:$B$14,MATCH(MIN($B$2:$B$14),$B$2:$B$14,0),1)

结果:

【讨论】:

  • 如果数字按升序排序,这看起来像是正确答案,因此值得一票。我可能会发布另一个答案,而不是假设它们已排序。
  • 嗨,汤姆,这似乎可行,但是未排序的版本会很棒,因为我不知道列表是否会在所有情况下都进行排序。非常感谢您的帮助。
【解决方案2】:

好吧,看起来相当简单的问题实际上非常棘手,因为在计算可能导致错误答案的差异时会遇到舍入错误。我最终将结果任意四舍五入到小数点后 10 位,然后再进行比较以得到四舍五入,但它看起来不是一个优雅的公式:

=MIN(IF((ROUND(ABS(ROUND(A2:INDEX(A:A,COUNTA(A:A)),0)-A2:INDEX(A:A,COUNTA(A:A))),10)=MIN(ROUND(ABS(ROUND(A2:INDEX(A:A,COUNTA(A:A)),0)-A2:INDEX(A:A,COUNTA(A:A))),10))),A2:INDEX(A:A,COUNTA(A:A))))

必须使用 CtrlShiftEnter

作为数组公式输入

假设数据中没有间隙(这会抛出 Counta 并且对于最小差异也会给出零结果)。

编辑

这只是一个实验,看看你是否使用十进制类型得到正确答案

Option Explicit
Option Base 1

Sub findClosestToInt()

Dim sht As Worksheet
Dim LastRow As Long, nRows As Long, nData As Long, nMins As Long
Dim i As Long
Dim data() As Variant, differences() As Variant, minData() As Variant
Dim minDiff As Variant, minValue As Variant, maxData As Variant


Set sht = ActiveSheet
LastRow = sht.Cells(sht.Rows.Count, "A").End(xlUp).Row
Debug.Print ("LR=" & LastRow)
nRows = LastRow - 1


ReDim data(LastRow - 1)
ReDim differences(LastRow - 1)

' store data as decimal

nData = 0
For i = 2 To LastRow
    If sht.Cells(i, 1) <> "" Then
        nData = nData + 1
        data(nData) = CDec(sht.Cells(i, 1))
    End If
Next i

ReDim Preserve data(nData)
ReDim differences(nData)

Debug.Print ("nData=" & nData)

' find differences from nearest integer

For i = 1 To nData
    differences(i) = Abs(data(i) - Round(data(i), 0))
    Debug.Print (differences(i)) ' no rounding errors
Next i

minDiff = Application.WorksheetFunction.Min(differences)

Debug.Print ("minDiff=" & minDiff)

ReDim minData(nData)

' find min of data where difference is equal to min difference

nMins = 0
For i = 1 To nData
    If differences(i) = minDiff Then
        nMins = nMins + 1
        minData(nMins) = data(i)
    End If
Next i

ReDim Preserve minData(nMins)

minValue = Application.WorksheetFunction.Min(minData)

Debug.Print ("minValue=" & minValue)

End Sub

结果是 1.99,这是正确的。如果你只是使用(比如说)double,你会得到错误的答案。

我认为,一旦找出差异,就可以使用工作表函数 Min。

如果需要,可以直接在数据中允许空白单元格 - 我认为 VBA 方法确实全面。

【讨论】:

  • 干杯!没有进一步四舍五入,第二批数据给了我 3.99,这是错误的。
  • 在我看来,最好的解决方案是 VBA 代码。快速清晰
  • 是的,好主意。我猜你可以选择使用 Decimal 数据类型,这样可以避免舍入错误。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-01-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多