代码之家  ›  专栏  ›  技术社区  ›  Aiden

Powershell:将分数转换为整数-令人惊讶的舍入行为

  •  7
  • Aiden  · 技术社区  · 6 年前

    我有一个关于整数和小数的有趣问题。

    假设我执行以下操作:

    [int] $a = 5/2
    $a
    

    我已经尝试了10次来确定,powershell总是会回来 2

    在这种情况下,是否有办法强制Powershell向上取整或向下取整?默认情况下,是否已将其设置为向下取整?

    我假设,根据机器和Powershell环境的不同,我可能会在某些点得到3个,在其他点得到2个。

    2 回复  |  直到 6 年前
        1
  •  12
  •   Vivek Kumar Singh    6 年前
    [Math]::Floor($a) --> 2
    [Math]::Ceiling($a)--> 3
    [Math]::Round($a) --> 2
    

    Floor 将给您前面的整数和 Ceiling 将提供后续整数。 但如果您想将其取整,请使用 Round 函数,它将遵循中点舍入( 中点的四舍五入历史上远离零 ),如下所示-

    [Math]::Round(2.50) --> 2
    [Math]::Round(2.51) --> 3
    [Math]::Round(2.49) --> 2
    [math]::Round(2.50,[System.MidpointRounding]::AwayFromZero) --> 3
    [math]::Round(2.49,[System.MidpointRounding]::AwayFromZero) --> 2
    [math]::Round(2.51,[System.MidpointRounding]::AwayFromZero) --> 3
    

    根据需要,您可以使用任意一个函数。

        2
  •  8
  •   mklement0    6 年前

    Vivek Kumar's answer 有帮助,但有一些令人困惑的方面。

    通常,将分数转换为整数总是涉及以下形式: 四舍五入 ; 在以下情况下: 铸造 含蓄的 转换时,编程语言通常使用 rounding to the nearest integer . 特别注意事项 适用于不明确的情况 分数部分精确的数字 .5 ,其中 不止一种策略 存在-不同的编程语言采用不同的策略。

    .NET框架 ,PowerShell是在其上构建的 总括术语 因为这些策略是 中点舍入 ,下面使用的具体策略名称指的是中点( .5. )作为 一半 为简洁起见(以下示例使用PowerShell语法,但适用于 全部的 .NET语言)。

    • 铸造 [int] 一成不变 雇佣 一半- 至平衡 四舍五入 ,其中数字的小数部分为 .5. 四舍五入到最接近的值 即使 整数(正或负):

      • [int] 2.5 -&燃气轮机; 2 (!) 情境的 向下 -舍入,因为整数部分恰好是 即使 和积极的
      • [int] 3.5 -&燃气轮机; 4 情境的 向上的 -四舍五入
      • 此舍入策略也适用于 含蓄的 PowerShell有时会执行到整数类型的转换-请参阅最后一节。
      • PowerShell 语法陷阱 :强制转换的优先级高于 / 所以 [int] 5/2 按预期工作;使用 [int] (5/2) .
    • 控制 中点舍入行为 ,使用 .净额 [Math] class' Round() 方法 :

      • 使用 [int] [Math]::Round($number, [MidpointRounding]::AwayFromZero) 得到 一半- 远离零度 四舍五入 (分数为的数字 .5. 四舍五入到最接近的整数 完全的 值为 更大的 ).

        • [Math]::Round(2.5, [MidpointRounding]::AwayFromZero) -&燃气轮机; 3
        • [Math]::Round(-2.5, [MidpointRounding]::AwayFromZero) -&燃气轮机; -3
        • 注:该 [数学] 方法(通常)返回 [double] ,因此您可能必须将结果强制转换为 [内景] (或不同的整数类型)以获取真正的整数。

    请注意 [Math]::Round() 不仅提供给- 整数 四舍五入,但也要达到 小数位数 ; 例如。,
    [Math]::Round(2.55, 1, [MidpointRounding]::AwayFromZero) 产量 2.6 . 谢谢 Ansgar Wiechers .


    其他形式的舍入:分数部分的特定值(除 0 )不相关:

    • 使用 [Math]::Truncate($number) 得到 接近零 四舍五入 (删除小数部分):

      • [Math]::Truncate(2.1) -&燃气轮机; 2. ; 同上 2.5 2.9 ,例如
      • [Math]::Truncate(-2.1) -&燃气轮机; -2
    • 使用 [Math]::Ceiling($number) 得到 朝向正无穷大 四舍五入 (四舍五入到最近的 大于或等于 整数):

      • [Math]::Ceiling(2.1) -&燃气轮机; 3.
      • [Math]::Ceiling(-2.1) -&燃气轮机; -2 (!)
    • 使用 [int] [Math]::Floor($number) 得到 朝向负无穷大 四舍五入 (四舍五入到最接近的值 更小或相等 整数):

      • [Math]::Floor(2.1) -&燃气轮机; 2.
      • [Math]::Floor(-2.1) -&燃气轮机; -3 (!)

    可选进一步阅读:

    PowerShell执行 含蓄的 使用此策略的转换:

    1..(2.5) 产量数组 1, 2 ,因为范围运算符表达式的端点, 2.5 ,被迫 [内景] 2. ,因此表达式实际上与 1..2

    因为PowerShell构建在。NET框架,它最终是 [Convert]::ToInt32() 这就是所谓的。

    背后的意图可能令人惊讶 半圆到均匀 策略是“在对四舍五入的数字求和时,将预期误差降至最低”, according to Wikipedia .

    维基百科关于舍入的页面有一节 rounding functions across programming languages .

    与相比。净额, JavaScript 例如,雇用 一半以上 四舍五入( Math.round(2.5) -&燃气轮机; 3. , Math.round(-2.5) -&燃气轮机; -2 )-中点舍入模式。NET甚至不提供。