我可能在这里遗漏了一些简单的事情,所以我提前道歉。我也知道可能有更好的方法,所以我也可以这样做。
我试图运行一个PowerShell脚本来查看一个值数组,比较它们以查看数组中两个元素之间差异的值。
以下是我用来测试的示例数据集,该数据集从CSV导入PowerShell:
1.0, 1.1, 1.2, 1.3, 1.4, 1.5, 1.7, 1.9, 2.0, 2.1, 2.2, 2.3, 2.4, 2.5, 2.7, 2.9, 3.0
我想要完成的是运行此列表并将第二个条目与第一个条目进行比较,第三个条目与第二个条目进行比较,第四个条目与第三个条目进行比较,等等,仅将元素添加到$export
它的值比前一个元素至少大0.2。
以下是我尝试的内容:
$import = get-content C:/pathtoCSVfile
$count = $import.Length-1;
$current=0;
Do
{
$current=$current+1;
$previous=$current-1
if (($import[$current]-$import[$previous]) -ge 0.2)
{
$export=$export+$import[$current]+"`r`n";
}
}
until ($current -eq $count)
现在我通过Trace on运行它,它将值分配给$current
和$previous
并按照每个循环上if
条件中的描述运行两者的减法通过,但只有2.7($import[14]-$import[13]
)的值是注册if条件已经满足,因此在$export
中只留下2.7的单个值。我预计其他值(1.7,1.9和2.9)也会添加到$export
变量中。
同样,这可能是我忽视的愚蠢/明显的东西,但我似乎无法弄明白。提前感谢您提供的任何见解。
答案 0 :(得分:5)
问题是小数部分在隐式使用的[double]
data type中没有完全表示,导致舍入错误导致您的{{1比较产生意外结果。
一个带有-ge 0.2
值的简单示例,这是PowerShell隐式使用的带有小数点的数字文字的内容:
[double]
如果您强制计算使用[decimal]
type而不是,则问题就会消失。
应用于上面的示例(将PS> 2.7 - 2.5 -ge 0.2
True # OK, but only accidentally so, due to the specific input numbers.
PS> 1.7 - 1.5 -ge 0.2
False # !! Due to the inexact internally binary [double] representation.
附加到PowerShell中的数字文字,使其成为d
):
[decimal]
应用于更加PowerShell惯用的代码重构:
PS> 1.7d - 1.5d -ge 0.2d
True # OK - Comparison is now exact, due to [decimal] values.
以上产量:
# Sample input; note that floating-point number literals such as 1.0 default to [double]
# Similarly, performing arithmetic on *strings* that look like floating-point numbers
# defaults to [double], and Import-Csv always creates string properties.
$numbers = 1.0, 1.1, 1.2, 1.3, 1.4, 1.5, 1.7, 1.9, 2.0, 2.1, 2.2, 2.3, 2.4, 2.5, 2.7, 2.9, 3.0
# Collect those array elements that are >= 0.2 than their preceding element
# in output *array* $exports.
$exports = foreach ($ndx in 1..($numbers.Count - 1)) {
if ([decimal] $numbers[$ndx] - [decimal] $numbers[$ndx-1] -ge 0.2d) {
$numbers[$ndx]
}
}
# Output the result array.
# To create a multi-line string representation, use $exports -join "`r`n"
$exports