当前位置: 首页 > 知识库问答 >
问题:

PowerShell[Math]::round有时不是rounding?

漆雕伟志
2023-03-14

我很难弄清楚为什么有些时候两个四舍五入的值的基础会给我一个非四舍五入的值。如果2.2-1.1=1.10000001。

我在PowerShell中有一个脚本块:

foreach($disk in $disks) 
{
    $size = $disk.Size
    $freespace = $disk.FreeSpace
    $percentFree = [Math]::Round(($freespace / $size) * 100)
    $sizeGB = [Math]::Round($size / 1073741824, 2)
    $freeSpaceGB = [Math]::Round($freespace / 1073741824, 2)
    $usedSpaceGB = $sizeGB - $freeSpaceGB

    #view the variable values in every iteration
    Write-Debug "`$size = $size"
    Write-Debug "`$freespace = $freespace"
    Write-Debug "`$percentFree = $percentFree%"
    Write-Debug "`$sizeGB = $sizeGB"
    Write-Debug "`$freeSpaceGB = $freeSpaceGB"
    Write-Debug "`$usedSpaceGB = $usedSpaceGB"
}

令人不安的部分是:

$usedSpaceGB = $sizeGB - $freeSpaceGB

    null

现在我通过舍入减法的结果来“修复”这个问题,但我想知道为什么会发生这种情况。我希望有人能帮我弄明白是怎么回事。

共有1个答案

臧弘和
2023-03-14

好吧,让我们试试这个答案...

我假设$disksWin32_logicaldisk实例的集合,在这种情况下,freespacesize属性是整数类型(特别是UINT64)。如果$disks包含其他类型,那么这两个属性可能是某种类型的整数,因为我们要处理的是字节计数。

这与问题有点无关,但在这一行...

$percentFree = [Math]::Round(($freespace / $size) * 100)
$percentFree.GetType()
$percentFree = [UInt64] [Math]::Round(($freespace / $size) * 100)
$sizeGB = [Math]::Round($size / 1073741824, 2)
$freeSpaceGB = [Math]::Round($freespace / 1073741824, 2)

...因为,当然,该方法重载必须返回浮点类型,因为根据定义,整数类型不能存储值的分数。因此,$sizegb$freespacegb包含浮点值(特别是double),所以当这一行...

$usedSpaceGB = $sizeGB - $freeSpaceGB

...是执行的$usedspacegb还将包含一个double,在这种情况下,只要它能够准确地表示结果值,所有的bets都将被取消。

希望这能解释为什么会发生这种情况。至于如何改进代码,首先我建议不要对中间值进行舍入...

$sizeGB = $size / 1073741824
$freeSpaceGB = $freespace / 1073741824
$usedSpaceGB = [Math]::Round($sizeGB - $freeSpaceGB, 2)
$sizeGB = $size / 1GB
$freeSpaceGB = $freespace / 1GB
$usedSpaceGB = [Math]::Round($sizeGB - $freeSpaceGB, 2)

这不会像您所看到的那样消除浮点近似值,但是$usedspacegb将更接近实际值,因为您不是基于已经舍入的$sizegb$freespacegb值进行计算(这会丢弃一些信息)。

在前面的代码片段中,$usedspacegb仍然是double,因此它仍然有可能计算到一些不能准确表示的值。由于该值是为了显示而格式化的,否则必须序列化为字符串(作为HTML),所以我将忘记Math.round,让string格式化像这样为您处理舍入...

$usedSpaceGBText = (($size - $freeSpace) / 1GB).ToString('N2')

...或者这个...

$usedSpaceGBText = '{0:N2}' -f (($size - $freeSpace) / 1GB)
 类似资料:
  • 本文向大家介绍Java 中的 Math. round(-1. 5) 等于多少?相关面试题,主要包含被问及Java 中的 Math. round(-1. 5) 等于多少?时的应答技巧和注意事项,需要的朋友参考一下 等于 -1。round()是四舍五入,注意负数5是舍的,例如:Math.round(1.5)值是2,Math.round(-1.5)值是-1。

  • 描述 (Description) round()方法接受一个数字,并返回舍入到最接近整数的数字的值 语法 (Syntax) 下面给出了JavaScript的round()方法的语法。 我们可以在CoffeeScript代码中使用相同的方法。 Math.round ( x ) 例子 (Example) 以下示例演示了CoffeeScript中round()方法的用法。 将此代码保存在名为math_

  • 描述 (Description) round方法返回最接近的long或int,由方法返回类型给出。 语法 (Syntax) 此方法有以下变体 - long round(double d) int round(float f) 参数 (Parameters) 这是参数的细节 - d - double或float原始数据类型。 f - 浮点原始数据类型。 返回值 (Return Value) 此方法

  • 描述 (Description) round()方法接受一个数字,并返回舍入到最接近整数的数字的值 语法 (Syntax) 下面给出了JavaScript的round()方法的语法。 我们可以在CoffeeScript代码中使用相同的方法。 Math.round ( x ) 例子 (Example) 以下示例演示了CoffeeScript中round()方法的用法。 将此代码保存在名为math_

  • 此方法返回舍入到最接近整数的数字的值。 语法 (Syntax) Number.round() 返回值 (Return Value) 返回舍入到最接近整数的数字的值。 例子 (Example) void main() { double n1 = 12.023; double n2 = 12.89; var value = n1.round(); print( val

  • round方法返回最接近的long或int,由方法返回类型给出。 语法 (Syntax) long round(double d) int round(float f) 参数 (Parameters) d - double或float原始数据类型 f - 浮点原始数据类型 返回值 (Return Value) 此方法返回最接近的long或int ,如方法的返回类型所示,返回参数。 例子 (Ex