我在我的一个脚本中做了一些补充,这里有一些简化的代码:
foreach($entry in $arr){
...
switch($entry.AccessRights)
{
"GenericRead" {$score = 1}
"GenericWrite" {$score = 2}
"GenericAll" {$score = 3}
default {$score = 0.1}
}
$users | where {$_.username -eq $entry.username} | % {$_.aclscore+=$score}
}
你会期望输出类似于123.5或类似的东西。但是在两者之间的某个时刻(当得分为0.1时)它偏离0.0000000000001正负值,所以我可能得到66,1000000000001甚至84,8999999999999的结果。
问题1:为什么?
问题2:除了事后的四舍五入,我还能做些什么来解决这个问题?
答案 0 :(得分:5)
在测试中,PowerShell隐式地将变量的数据类型转换为[double]
。相反,明确地转换为[decimal]
这绝不是一次深入的比较;我建议你阅读this table of datatypes并在线查看更完整的解释,因为这是非常基础的,与语言无关。
<强>代码强>
foreach($entry in $arr){
...
switch($entry.AccessRights)
{
"GenericRead" {[decimal]$score = 1}
"GenericWrite" {[decimal]$score = 2}
"GenericAll" {[decimal]$score = 3}
default {[decimal]$score = 0.1}
}
$users | where {$_.username -eq $entry.username} | % {$_.aclscore+=$score}
}
修改 - 进一步说明
双数据类型缺乏精确性是因为数字存储在binary中,而某些数字不能用二进制表示。
Walter Mitty的评论提供了1/3
的一个很好的例子,这个数字不能用十进制的有限位数或二进制来精确表达:
1/3 = 0.333333333..... [decimal]
1/3 = 0.010101010..... [binary]
同样,分数1/10
cannot be expressed exactly in binary。而它可以十进制。
1/10 = 0.1 [decimal]
1/10 = 0.000110011.... [binary]