Powershell添加不需要的小数(添加)

Pau*_*aul 1 powershell powershell-5.0

我在我的一个脚本中做了一些补充,这里有一些简化的代码:

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}
}
Run Code Online (Sandbox Code Playgroud)

你会期望输出类似于123.5或类似的东西.但是在两者之间的某个时刻(当得分为0.1时)它会偏离0.0000000000001正负,所以我可能得到66,1000000000001甚至84,8999999999999的结果.

问题1:为什么?

问题2:除了之后的舍入,我还能做些什么来解决这个问题?

gms*_*man 5

在测试时,PowerShell会隐式转换为变量的数据类型[double].相反,明确地转换为[decimal]

  • Double数据类型可以包含多种值,但牺牲了精确的精度.
  • 十进制使用更多内存(12个字节与双重中的8个相反)并且具有更短的值范围但保留精度.

这绝不是一次深入的比较; 我建议你阅读这个数据类型表并在线查看更完整的解释,因为这是非常基础的,并且与语言无关.

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}

}
Run Code Online (Sandbox Code Playgroud)

编辑 - 进一步说明

双数据类型缺乏精度,因为数字以二进制形式存储,而某些数字不能以二进制形式精确表示.

沃尔特·米蒂的评论提供了一个很好的例子1/3,一个数字不能用十进制或二进制的有限位数精确表达:

1/3 = 0.333333333..... [decimal]
1/3 = 0.010101010..... [binary]
Run Code Online (Sandbox Code Playgroud)

类似地,该分数1/10 不能精确地以二进制表示.而它可以十进制.

1/10 = 0.1             [decimal]
1/10 = 0.000110011.... [binary]
Run Code Online (Sandbox Code Playgroud)

  • 值得谷歌搜索"浮点运算" (2认同)
  • 保留decmal fractins的精确度,是的.对于三分之一的数字,double和decimal都表示它是近似值. (2认同)